kiln-ai 0.15.0__py3-none-any.whl → 0.16.0__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.
Files changed (45) hide show
  1. kiln_ai/adapters/eval/eval_runner.py +5 -64
  2. kiln_ai/adapters/eval/g_eval.py +3 -3
  3. kiln_ai/adapters/fine_tune/dataset_formatter.py +124 -34
  4. kiln_ai/adapters/fine_tune/test_dataset_formatter.py +264 -7
  5. kiln_ai/adapters/ml_model_list.py +478 -4
  6. kiln_ai/adapters/model_adapters/base_adapter.py +26 -8
  7. kiln_ai/adapters/model_adapters/litellm_adapter.py +41 -7
  8. kiln_ai/adapters/model_adapters/test_base_adapter.py +74 -2
  9. kiln_ai/adapters/model_adapters/test_litellm_adapter.py +65 -1
  10. kiln_ai/adapters/model_adapters/test_saving_adapter_results.py +3 -2
  11. kiln_ai/adapters/model_adapters/test_structured_output.py +4 -6
  12. kiln_ai/adapters/parsers/base_parser.py +0 -3
  13. kiln_ai/adapters/parsers/parser_registry.py +5 -3
  14. kiln_ai/adapters/parsers/r1_parser.py +17 -2
  15. kiln_ai/adapters/parsers/request_formatters.py +40 -0
  16. kiln_ai/adapters/parsers/test_parser_registry.py +2 -2
  17. kiln_ai/adapters/parsers/test_r1_parser.py +44 -1
  18. kiln_ai/adapters/parsers/test_request_formatters.py +76 -0
  19. kiln_ai/adapters/prompt_builders.py +14 -1
  20. kiln_ai/adapters/provider_tools.py +18 -1
  21. kiln_ai/adapters/repair/test_repair_task.py +3 -2
  22. kiln_ai/adapters/test_prompt_builders.py +24 -3
  23. kiln_ai/adapters/test_provider_tools.py +70 -1
  24. kiln_ai/datamodel/__init__.py +2 -0
  25. kiln_ai/datamodel/datamodel_enums.py +14 -0
  26. kiln_ai/datamodel/dataset_filters.py +69 -1
  27. kiln_ai/datamodel/dataset_split.py +4 -0
  28. kiln_ai/datamodel/eval.py +8 -0
  29. kiln_ai/datamodel/finetune.py +1 -0
  30. kiln_ai/datamodel/prompt_id.py +1 -0
  31. kiln_ai/datamodel/task_output.py +1 -1
  32. kiln_ai/datamodel/task_run.py +39 -7
  33. kiln_ai/datamodel/test_basemodel.py +3 -7
  34. kiln_ai/datamodel/test_dataset_filters.py +82 -0
  35. kiln_ai/datamodel/test_dataset_split.py +2 -0
  36. kiln_ai/datamodel/test_example_models.py +54 -0
  37. kiln_ai/datamodel/test_models.py +50 -2
  38. kiln_ai/utils/async_job_runner.py +106 -0
  39. kiln_ai/utils/dataset_import.py +80 -18
  40. kiln_ai/utils/test_async_job_runner.py +199 -0
  41. kiln_ai/utils/test_dataset_import.py +242 -10
  42. {kiln_ai-0.15.0.dist-info → kiln_ai-0.16.0.dist-info}/METADATA +1 -1
  43. {kiln_ai-0.15.0.dist-info → kiln_ai-0.16.0.dist-info}/RECORD +45 -41
  44. {kiln_ai-0.15.0.dist-info → kiln_ai-0.16.0.dist-info}/WHEEL +0 -0
  45. {kiln_ai-0.15.0.dist-info → kiln_ai-0.16.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -126,6 +126,22 @@ class ModelName(str, Enum):
126
126
  deepseek_r1_distill_llama_8b = "deepseek_r1_distill_llama_8b"
127
127
  dolphin_2_9_8x22b = "dolphin_2_9_8x22b"
128
128
  grok_2 = "grok_2"
129
+ qwen_3_0p6b = "qwen_3_0p6b"
130
+ qwen_3_0p6b_no_thinking = "qwen_3_0p6b_no_thinking"
131
+ qwen_3_1p7b = "qwen_3_1p7b"
132
+ qwen_3_1p7b_no_thinking = "qwen_3_1p7b_no_thinking"
133
+ qwen_3_4b = "qwen_3_4b"
134
+ qwen_3_4b_no_thinking = "qwen_3_4b_no_thinking"
135
+ qwen_3_8b = "qwen_3_8b"
136
+ qwen_3_8b_no_thinking = "qwen_3_8b_no_thinking"
137
+ qwen_3_14b = "qwen_3_14b"
138
+ qwen_3_14b_no_thinking = "qwen_3_14b_no_thinking"
139
+ qwen_3_30b_a3b = "qwen_3_30b_a3b"
140
+ qwen_3_30b_a3b_no_thinking = "qwen_3_30b_a3b_no_thinking"
141
+ qwen_3_32b = "qwen_3_32b"
142
+ qwen_3_32b_no_thinking = "qwen_3_32b_no_thinking"
143
+ qwen_3_235b_a22b = "qwen_3_235b_a22b"
144
+ qwen_3_235b_a22b_no_thinking = "qwen_3_235b_a22b_no_thinking"
129
145
 
130
146
 
131
147
  class ModelParserID(str, Enum):
@@ -134,6 +150,15 @@ class ModelParserID(str, Enum):
134
150
  """
135
151
 
136
152
  r1_thinking = "r1_thinking"
153
+ optional_r1_thinking = "optional_r1_thinking"
154
+
155
+
156
+ class ModelFormatterID(str, Enum):
157
+ """
158
+ Enumeration of supported model formatters.
159
+ """
160
+
161
+ qwen3_style_no_think = "qwen3_style_no_think"
137
162
 
138
163
 
139
164
  class KilnModelProvider(BaseModel):
@@ -155,12 +180,15 @@ class KilnModelProvider(BaseModel):
155
180
  model_id: str | None = None
156
181
  supports_structured_output: bool = True
157
182
  supports_data_gen: bool = True
183
+ suggested_for_data_gen: bool = False
158
184
  untested_model: bool = False
159
185
  provider_finetune_id: str | None = None
160
186
  structured_output_mode: StructuredOutputMode = StructuredOutputMode.default
161
187
  parser: ModelParserID | None = None
188
+ formatter: ModelFormatterID | None = None
162
189
  reasoning_capable: bool = False
163
190
  supports_logprobs: bool = False
191
+ suggested_for_evals: bool = False
164
192
 
165
193
  # TODO P1: Need a more generalized way to handle custom provider parameters.
166
194
  # Making them quite declarative here for now, isolating provider specific logic
@@ -205,16 +233,22 @@ built_in_models: List[KilnModel] = [
205
233
  provider_finetune_id="gpt-4.1-2025-04-14",
206
234
  structured_output_mode=StructuredOutputMode.json_schema,
207
235
  supports_logprobs=True,
236
+ suggested_for_data_gen=True,
237
+ suggested_for_evals=True,
208
238
  ),
209
239
  KilnModelProvider(
210
240
  name=ModelProviderName.openrouter,
211
241
  model_id="openai/gpt-4.1",
212
242
  structured_output_mode=StructuredOutputMode.json_schema,
213
243
  supports_logprobs=True,
244
+ suggested_for_data_gen=True,
245
+ suggested_for_evals=True,
214
246
  ),
215
247
  KilnModelProvider(
216
248
  name=ModelProviderName.azure_openai,
217
249
  model_id="gpt-4.1",
250
+ suggested_for_data_gen=True,
251
+ suggested_for_evals=True,
218
252
  ),
219
253
  ],
220
254
  ),
@@ -230,16 +264,22 @@ built_in_models: List[KilnModel] = [
230
264
  provider_finetune_id="gpt-4.1-mini-2025-04-14",
231
265
  structured_output_mode=StructuredOutputMode.json_schema,
232
266
  supports_logprobs=True,
267
+ suggested_for_data_gen=True,
268
+ suggested_for_evals=True,
233
269
  ),
234
270
  KilnModelProvider(
235
271
  name=ModelProviderName.openrouter,
236
272
  model_id="openai/gpt-4.1-mini",
237
273
  structured_output_mode=StructuredOutputMode.json_schema,
238
274
  supports_logprobs=True,
275
+ suggested_for_data_gen=True,
276
+ suggested_for_evals=True,
239
277
  ),
240
278
  KilnModelProvider(
241
279
  name=ModelProviderName.azure_openai,
242
280
  model_id="gpt-4.1-mini",
281
+ suggested_for_data_gen=True,
282
+ suggested_for_evals=True,
243
283
  ),
244
284
  ],
245
285
  ),
@@ -625,11 +665,15 @@ built_in_models: List[KilnModel] = [
625
665
  name=ModelProviderName.openrouter,
626
666
  structured_output_mode=StructuredOutputMode.function_calling,
627
667
  model_id="anthropic/claude-3.7-sonnet",
668
+ suggested_for_data_gen=True,
669
+ suggested_for_evals=True,
628
670
  ),
629
671
  KilnModelProvider(
630
672
  name=ModelProviderName.anthropic,
631
673
  model_id="claude-3-7-sonnet-20250219",
632
674
  structured_output_mode=StructuredOutputMode.function_calling,
675
+ suggested_for_data_gen=True,
676
+ suggested_for_evals=True,
633
677
  ),
634
678
  ],
635
679
  ),
@@ -666,16 +710,22 @@ built_in_models: List[KilnModel] = [
666
710
  name=ModelProviderName.openrouter,
667
711
  model_id="google/gemini-2.5-pro-preview-03-25",
668
712
  structured_output_mode=StructuredOutputMode.json_schema,
713
+ suggested_for_data_gen=True,
714
+ suggested_for_evals=True,
669
715
  ),
670
716
  KilnModelProvider(
671
717
  name=ModelProviderName.gemini_api,
672
718
  model_id="gemini-2.5-pro-preview-03-25",
673
719
  structured_output_mode=StructuredOutputMode.json_schema,
720
+ suggested_for_data_gen=True,
721
+ suggested_for_evals=True,
674
722
  ),
675
723
  KilnModelProvider(
676
724
  name=ModelProviderName.vertex,
677
725
  model_id="gemini-2.5-pro-preview-03-25",
678
726
  structured_output_mode=StructuredOutputMode.json_schema,
727
+ suggested_for_data_gen=True,
728
+ suggested_for_evals=True,
679
729
  ),
680
730
  ],
681
731
  ),
@@ -1068,10 +1118,6 @@ built_in_models: List[KilnModel] = [
1068
1118
  name=ModelName.llama_3_2_11b,
1069
1119
  friendly_name="Llama 3.2 11B",
1070
1120
  providers=[
1071
- KilnModelProvider(
1072
- name=ModelProviderName.groq,
1073
- model_id="llama-3.2-11b-vision-preview",
1074
- ),
1075
1121
  KilnModelProvider(
1076
1122
  name=ModelProviderName.openrouter,
1077
1123
  # Best mode, but fails to often to enable without warning
@@ -1578,6 +1624,8 @@ built_in_models: List[KilnModel] = [
1578
1624
  reasoning_capable=True,
1579
1625
  r1_openrouter_options=True,
1580
1626
  require_openrouter_reasoning=True,
1627
+ suggested_for_data_gen=True,
1628
+ suggested_for_evals=True,
1581
1629
  ),
1582
1630
  KilnModelProvider(
1583
1631
  name=ModelProviderName.fireworks_ai,
@@ -1585,6 +1633,8 @@ built_in_models: List[KilnModel] = [
1585
1633
  parser=ModelParserID.r1_thinking,
1586
1634
  structured_output_mode=StructuredOutputMode.json_instructions,
1587
1635
  reasoning_capable=True,
1636
+ suggested_for_data_gen=True,
1637
+ suggested_for_evals=True,
1588
1638
  ),
1589
1639
  KilnModelProvider(
1590
1640
  # I want your RAM
@@ -1593,6 +1643,8 @@ built_in_models: List[KilnModel] = [
1593
1643
  parser=ModelParserID.r1_thinking,
1594
1644
  structured_output_mode=StructuredOutputMode.json_instructions,
1595
1645
  reasoning_capable=True,
1646
+ suggested_for_data_gen=True,
1647
+ suggested_for_evals=True,
1596
1648
  ),
1597
1649
  KilnModelProvider(
1598
1650
  name=ModelProviderName.together_ai,
@@ -1600,6 +1652,8 @@ built_in_models: List[KilnModel] = [
1600
1652
  structured_output_mode=StructuredOutputMode.json_instructions,
1601
1653
  parser=ModelParserID.r1_thinking,
1602
1654
  reasoning_capable=True,
1655
+ suggested_for_data_gen=True,
1656
+ suggested_for_evals=True,
1603
1657
  ),
1604
1658
  ],
1605
1659
  ),
@@ -1819,4 +1873,424 @@ built_in_models: List[KilnModel] = [
1819
1873
  ),
1820
1874
  ],
1821
1875
  ),
1876
+ # Qwen 3 0.6B
1877
+ KilnModel(
1878
+ family=ModelFamily.qwen,
1879
+ name=ModelName.qwen_3_0p6b,
1880
+ friendly_name="Qwen 3 0.6B",
1881
+ providers=[
1882
+ KilnModelProvider(
1883
+ name=ModelProviderName.openrouter,
1884
+ model_id="qwen/qwen3-0.6b-04-28:free",
1885
+ structured_output_mode=StructuredOutputMode.json_instructions,
1886
+ reasoning_capable=True,
1887
+ require_openrouter_reasoning=True,
1888
+ r1_openrouter_options=True,
1889
+ parser=ModelParserID.r1_thinking,
1890
+ supports_data_gen=False,
1891
+ ),
1892
+ KilnModelProvider(
1893
+ name=ModelProviderName.ollama,
1894
+ model_id="qwen3:0.6b",
1895
+ supports_data_gen=False,
1896
+ reasoning_capable=True,
1897
+ structured_output_mode=StructuredOutputMode.json_schema,
1898
+ ),
1899
+ ],
1900
+ ),
1901
+ # Qwen 3 0.6B Non-Thinking -- not respecting /no_think tag, skipping
1902
+ # Qwen 3 1.7B
1903
+ KilnModel(
1904
+ family=ModelFamily.qwen,
1905
+ name=ModelName.qwen_3_1p7b,
1906
+ friendly_name="Qwen 3 1.7B",
1907
+ providers=[
1908
+ KilnModelProvider(
1909
+ name=ModelProviderName.openrouter,
1910
+ model_id="qwen/qwen3-1.7b:free",
1911
+ structured_output_mode=StructuredOutputMode.json_instructions,
1912
+ reasoning_capable=True,
1913
+ require_openrouter_reasoning=True,
1914
+ r1_openrouter_options=True,
1915
+ parser=ModelParserID.r1_thinking,
1916
+ supports_data_gen=False,
1917
+ ),
1918
+ KilnModelProvider(
1919
+ name=ModelProviderName.ollama,
1920
+ model_id="qwen3:1.7b",
1921
+ supports_data_gen=False,
1922
+ reasoning_capable=True,
1923
+ structured_output_mode=StructuredOutputMode.json_schema,
1924
+ ),
1925
+ ],
1926
+ ),
1927
+ # Qwen 3 1.7B Non-Thinking
1928
+ KilnModel(
1929
+ family=ModelFamily.qwen,
1930
+ name=ModelName.qwen_3_1p7b_no_thinking,
1931
+ friendly_name="Qwen 3 1.7B Non-Thinking",
1932
+ providers=[
1933
+ KilnModelProvider(
1934
+ name=ModelProviderName.openrouter,
1935
+ model_id="qwen/qwen3-1.7b:free",
1936
+ structured_output_mode=StructuredOutputMode.json_instructions,
1937
+ formatter=ModelFormatterID.qwen3_style_no_think,
1938
+ supports_data_gen=False,
1939
+ parser=ModelParserID.optional_r1_thinking,
1940
+ ),
1941
+ KilnModelProvider(
1942
+ name=ModelProviderName.ollama,
1943
+ model_id="qwen3:1.7b",
1944
+ formatter=ModelFormatterID.qwen3_style_no_think,
1945
+ supports_data_gen=False,
1946
+ structured_output_mode=StructuredOutputMode.json_schema,
1947
+ ),
1948
+ ],
1949
+ ),
1950
+ # Qwen 3 4B
1951
+ KilnModel(
1952
+ family=ModelFamily.qwen,
1953
+ name=ModelName.qwen_3_4b,
1954
+ friendly_name="Qwen 3 4B",
1955
+ providers=[
1956
+ KilnModelProvider(
1957
+ name=ModelProviderName.openrouter,
1958
+ model_id="qwen/qwen3-4b:free",
1959
+ structured_output_mode=StructuredOutputMode.json_instructions,
1960
+ reasoning_capable=True,
1961
+ require_openrouter_reasoning=True,
1962
+ r1_openrouter_options=True,
1963
+ parser=ModelParserID.r1_thinking,
1964
+ supports_data_gen=False,
1965
+ ),
1966
+ KilnModelProvider(
1967
+ name=ModelProviderName.ollama,
1968
+ model_id="qwen3:4b",
1969
+ supports_data_gen=False,
1970
+ reasoning_capable=True,
1971
+ structured_output_mode=StructuredOutputMode.json_schema,
1972
+ ),
1973
+ ],
1974
+ ),
1975
+ # Qwen 3 4B Non-Thinking
1976
+ KilnModel(
1977
+ family=ModelFamily.qwen,
1978
+ name=ModelName.qwen_3_4b_no_thinking,
1979
+ friendly_name="Qwen 3 4B Non-Thinking",
1980
+ providers=[
1981
+ KilnModelProvider(
1982
+ name=ModelProviderName.openrouter,
1983
+ model_id="qwen/qwen3-4b:free",
1984
+ structured_output_mode=StructuredOutputMode.json_instructions,
1985
+ formatter=ModelFormatterID.qwen3_style_no_think,
1986
+ supports_data_gen=False,
1987
+ parser=ModelParserID.optional_r1_thinking,
1988
+ ),
1989
+ KilnModelProvider(
1990
+ name=ModelProviderName.ollama,
1991
+ model_id="qwen3:4b",
1992
+ structured_output_mode=StructuredOutputMode.json_schema,
1993
+ formatter=ModelFormatterID.qwen3_style_no_think,
1994
+ supports_data_gen=False,
1995
+ ),
1996
+ ],
1997
+ ),
1998
+ # Qwen 3 8B
1999
+ KilnModel(
2000
+ family=ModelFamily.qwen,
2001
+ name=ModelName.qwen_3_8b,
2002
+ friendly_name="Qwen 3 8B",
2003
+ providers=[
2004
+ KilnModelProvider(
2005
+ name=ModelProviderName.openrouter,
2006
+ model_id="qwen/qwen3-8b",
2007
+ supports_structured_output=True,
2008
+ structured_output_mode=StructuredOutputMode.json_instructions,
2009
+ reasoning_capable=True,
2010
+ require_openrouter_reasoning=True,
2011
+ r1_openrouter_options=True,
2012
+ parser=ModelParserID.r1_thinking,
2013
+ supports_data_gen=False,
2014
+ ),
2015
+ KilnModelProvider(
2016
+ name=ModelProviderName.ollama,
2017
+ model_id="qwen3:8b",
2018
+ supports_data_gen=False,
2019
+ reasoning_capable=True,
2020
+ structured_output_mode=StructuredOutputMode.json_schema,
2021
+ ),
2022
+ ],
2023
+ ),
2024
+ # Qwen 3 8B Non-Thinking
2025
+ KilnModel(
2026
+ family=ModelFamily.qwen,
2027
+ name=ModelName.qwen_3_8b_no_thinking,
2028
+ friendly_name="Qwen 3 8B Non-Thinking",
2029
+ providers=[
2030
+ KilnModelProvider(
2031
+ name=ModelProviderName.openrouter,
2032
+ model_id="qwen/qwen3-8b",
2033
+ structured_output_mode=StructuredOutputMode.json_instructions,
2034
+ formatter=ModelFormatterID.qwen3_style_no_think,
2035
+ supports_data_gen=False,
2036
+ parser=ModelParserID.optional_r1_thinking,
2037
+ ),
2038
+ KilnModelProvider(
2039
+ name=ModelProviderName.ollama,
2040
+ model_id="qwen3:8b",
2041
+ structured_output_mode=StructuredOutputMode.json_schema,
2042
+ formatter=ModelFormatterID.qwen3_style_no_think,
2043
+ supports_data_gen=False,
2044
+ ),
2045
+ ],
2046
+ ),
2047
+ # Qwen 3 14B
2048
+ KilnModel(
2049
+ family=ModelFamily.qwen,
2050
+ name=ModelName.qwen_3_14b,
2051
+ friendly_name="Qwen 3 14B",
2052
+ providers=[
2053
+ KilnModelProvider(
2054
+ name=ModelProviderName.openrouter,
2055
+ model_id="qwen/qwen3-14b",
2056
+ structured_output_mode=StructuredOutputMode.json_instructions,
2057
+ reasoning_capable=True,
2058
+ require_openrouter_reasoning=True,
2059
+ r1_openrouter_options=True,
2060
+ parser=ModelParserID.r1_thinking,
2061
+ supports_data_gen=True,
2062
+ ),
2063
+ KilnModelProvider(
2064
+ name=ModelProviderName.ollama,
2065
+ model_id="qwen3:14b",
2066
+ supports_data_gen=True,
2067
+ reasoning_capable=True,
2068
+ structured_output_mode=StructuredOutputMode.json_schema,
2069
+ ),
2070
+ ],
2071
+ ),
2072
+ # Qwen 3 14B Non-Thinking
2073
+ KilnModel(
2074
+ family=ModelFamily.qwen,
2075
+ name=ModelName.qwen_3_14b_no_thinking,
2076
+ friendly_name="Qwen 3 14B Non-Thinking",
2077
+ providers=[
2078
+ KilnModelProvider(
2079
+ name=ModelProviderName.openrouter,
2080
+ model_id="qwen/qwen3-14b",
2081
+ structured_output_mode=StructuredOutputMode.json_instructions,
2082
+ formatter=ModelFormatterID.qwen3_style_no_think,
2083
+ supports_data_gen=True,
2084
+ parser=ModelParserID.optional_r1_thinking,
2085
+ ),
2086
+ KilnModelProvider(
2087
+ name=ModelProviderName.ollama,
2088
+ model_id="qwen3:14b",
2089
+ formatter=ModelFormatterID.qwen3_style_no_think,
2090
+ supports_data_gen=True,
2091
+ structured_output_mode=StructuredOutputMode.json_schema,
2092
+ ),
2093
+ ],
2094
+ ),
2095
+ # Qwen 3 30B (3B Active)
2096
+ KilnModel(
2097
+ family=ModelFamily.qwen,
2098
+ name=ModelName.qwen_3_30b_a3b,
2099
+ friendly_name="Qwen 3 30B (3B Active)",
2100
+ providers=[
2101
+ KilnModelProvider(
2102
+ name=ModelProviderName.openrouter,
2103
+ model_id="qwen/qwen3-30b-a3b",
2104
+ structured_output_mode=StructuredOutputMode.json_instructions,
2105
+ reasoning_capable=True,
2106
+ require_openrouter_reasoning=True,
2107
+ r1_openrouter_options=True,
2108
+ parser=ModelParserID.r1_thinking,
2109
+ supports_data_gen=True,
2110
+ ),
2111
+ KilnModelProvider(
2112
+ name=ModelProviderName.ollama,
2113
+ model_id="qwen3:30b-a3b",
2114
+ supports_data_gen=True,
2115
+ reasoning_capable=True,
2116
+ structured_output_mode=StructuredOutputMode.json_schema,
2117
+ ),
2118
+ KilnModelProvider(
2119
+ name=ModelProviderName.fireworks_ai,
2120
+ model_id="accounts/fireworks/models/qwen3-30b-a3b",
2121
+ supports_data_gen=True,
2122
+ reasoning_capable=True,
2123
+ structured_output_mode=StructuredOutputMode.json_instructions,
2124
+ parser=ModelParserID.r1_thinking,
2125
+ ),
2126
+ ],
2127
+ ),
2128
+ # Qwen 3 30B (3B Active) Non-Thinking
2129
+ KilnModel(
2130
+ family=ModelFamily.qwen,
2131
+ name=ModelName.qwen_3_30b_a3b_no_thinking,
2132
+ friendly_name="Qwen 3 30B (3B Active) Non-Thinking",
2133
+ providers=[
2134
+ KilnModelProvider(
2135
+ name=ModelProviderName.openrouter,
2136
+ model_id="qwen/qwen3-30b-a3b",
2137
+ structured_output_mode=StructuredOutputMode.json_instructions,
2138
+ formatter=ModelFormatterID.qwen3_style_no_think,
2139
+ supports_data_gen=True,
2140
+ parser=ModelParserID.optional_r1_thinking,
2141
+ ),
2142
+ KilnModelProvider(
2143
+ name=ModelProviderName.ollama,
2144
+ model_id="qwen3:30b-a3b",
2145
+ structured_output_mode=StructuredOutputMode.json_schema,
2146
+ formatter=ModelFormatterID.qwen3_style_no_think,
2147
+ supports_data_gen=True,
2148
+ ),
2149
+ KilnModelProvider(
2150
+ name=ModelProviderName.fireworks_ai,
2151
+ model_id="accounts/fireworks/models/qwen3-30b-a3b",
2152
+ supports_data_gen=True,
2153
+ formatter=ModelFormatterID.qwen3_style_no_think,
2154
+ structured_output_mode=StructuredOutputMode.json_instructions,
2155
+ parser=ModelParserID.optional_r1_thinking,
2156
+ ),
2157
+ ],
2158
+ ),
2159
+ # Qwen 3 32B
2160
+ KilnModel(
2161
+ family=ModelFamily.qwen,
2162
+ name=ModelName.qwen_3_32b,
2163
+ friendly_name="Qwen 3 32B",
2164
+ providers=[
2165
+ KilnModelProvider(
2166
+ name=ModelProviderName.openrouter,
2167
+ model_id="qwen/qwen3-32b",
2168
+ reasoning_capable=True,
2169
+ require_openrouter_reasoning=True,
2170
+ r1_openrouter_options=True,
2171
+ structured_output_mode=StructuredOutputMode.json_instructions,
2172
+ parser=ModelParserID.r1_thinking,
2173
+ supports_data_gen=True,
2174
+ ),
2175
+ KilnModelProvider(
2176
+ name=ModelProviderName.ollama,
2177
+ model_id="qwen3:32b",
2178
+ supports_data_gen=True,
2179
+ reasoning_capable=True,
2180
+ structured_output_mode=StructuredOutputMode.json_schema,
2181
+ ),
2182
+ ],
2183
+ ),
2184
+ # Qwen 3 32B No Thinking
2185
+ KilnModel(
2186
+ family=ModelFamily.qwen,
2187
+ name=ModelName.qwen_3_32b_no_thinking,
2188
+ friendly_name="Qwen 3 32B Non-Thinking",
2189
+ providers=[
2190
+ KilnModelProvider(
2191
+ name=ModelProviderName.openrouter,
2192
+ model_id="qwen/qwen3-32b",
2193
+ structured_output_mode=StructuredOutputMode.json_instructions,
2194
+ formatter=ModelFormatterID.qwen3_style_no_think,
2195
+ supports_data_gen=True,
2196
+ parser=ModelParserID.optional_r1_thinking,
2197
+ ),
2198
+ KilnModelProvider(
2199
+ name=ModelProviderName.ollama,
2200
+ model_id="qwen3:32b",
2201
+ structured_output_mode=StructuredOutputMode.json_schema,
2202
+ formatter=ModelFormatterID.qwen3_style_no_think,
2203
+ supports_data_gen=True,
2204
+ ),
2205
+ ],
2206
+ ),
2207
+ # Qwen 3 235B (22B Active)
2208
+ KilnModel(
2209
+ family=ModelFamily.qwen,
2210
+ name=ModelName.qwen_3_235b_a22b,
2211
+ friendly_name="Qwen 3 235B (22B Active)",
2212
+ providers=[
2213
+ KilnModelProvider(
2214
+ name=ModelProviderName.openrouter,
2215
+ model_id="qwen/qwen3-235b-a22b",
2216
+ reasoning_capable=True,
2217
+ require_openrouter_reasoning=True,
2218
+ supports_data_gen=True,
2219
+ suggested_for_data_gen=True,
2220
+ r1_openrouter_options=True,
2221
+ structured_output_mode=StructuredOutputMode.json_instructions,
2222
+ parser=ModelParserID.r1_thinking,
2223
+ ),
2224
+ KilnModelProvider(
2225
+ name=ModelProviderName.ollama,
2226
+ model_id="qwen3:235b-a22b",
2227
+ supports_data_gen=True,
2228
+ reasoning_capable=True,
2229
+ structured_output_mode=StructuredOutputMode.json_schema,
2230
+ ),
2231
+ KilnModelProvider(
2232
+ name=ModelProviderName.fireworks_ai,
2233
+ model_id="accounts/fireworks/models/qwen3-235b-a22b",
2234
+ supports_data_gen=True,
2235
+ reasoning_capable=True,
2236
+ structured_output_mode=StructuredOutputMode.json_instructions,
2237
+ parser=ModelParserID.r1_thinking,
2238
+ ),
2239
+ KilnModelProvider(
2240
+ name=ModelProviderName.together_ai,
2241
+ model_id="Qwen/Qwen3-235B-A22B-fp8-tput",
2242
+ supports_data_gen=True,
2243
+ reasoning_capable=True,
2244
+ structured_output_mode=StructuredOutputMode.json_instructions,
2245
+ parser=ModelParserID.r1_thinking,
2246
+ ),
2247
+ ],
2248
+ ),
2249
+ # Qwen 3 235B (22B Active) Non-Thinking
2250
+ KilnModel(
2251
+ family=ModelFamily.qwen,
2252
+ name=ModelName.qwen_3_235b_a22b_no_thinking,
2253
+ friendly_name="Qwen 3 235B (22B Active) Non-Thinking",
2254
+ providers=[
2255
+ KilnModelProvider(
2256
+ name=ModelProviderName.openrouter,
2257
+ model_id="qwen/qwen3-235b-a22b",
2258
+ structured_output_mode=StructuredOutputMode.json_instructions,
2259
+ formatter=ModelFormatterID.qwen3_style_no_think,
2260
+ supports_data_gen=True,
2261
+ reasoning_capable=False,
2262
+ parser=ModelParserID.optional_r1_thinking,
2263
+ ),
2264
+ KilnModelProvider(
2265
+ name=ModelProviderName.ollama,
2266
+ model_id="qwen3:235b-a22b",
2267
+ structured_output_mode=StructuredOutputMode.json_schema,
2268
+ formatter=ModelFormatterID.qwen3_style_no_think,
2269
+ supports_data_gen=True,
2270
+ ),
2271
+ KilnModelProvider(
2272
+ name=ModelProviderName.fireworks_ai,
2273
+ model_id="accounts/fireworks/models/qwen3-235b-a22b",
2274
+ supports_data_gen=True,
2275
+ formatter=ModelFormatterID.qwen3_style_no_think,
2276
+ structured_output_mode=StructuredOutputMode.json_instructions,
2277
+ parser=ModelParserID.optional_r1_thinking,
2278
+ ),
2279
+ KilnModelProvider(
2280
+ name=ModelProviderName.together_ai,
2281
+ model_id="Qwen/Qwen3-235B-A22B-fp8-tput",
2282
+ supports_data_gen=True,
2283
+ formatter=ModelFormatterID.qwen3_style_no_think,
2284
+ structured_output_mode=StructuredOutputMode.json_instructions,
2285
+ parser=ModelParserID.optional_r1_thinking,
2286
+ ),
2287
+ ],
2288
+ ),
1822
2289
  ]
2290
+
2291
+
2292
+ def get_model_by_name(name: ModelName) -> KilnModel:
2293
+ for model in built_in_models:
2294
+ if model.name == name:
2295
+ return model
2296
+ raise ValueError(f"Model {name} not found in the list of built-in models")
@@ -8,10 +8,18 @@ import jsonschema
8
8
  from kiln_ai.adapters.ml_model_list import KilnModelProvider, StructuredOutputMode
9
9
  from kiln_ai.adapters.parsers.json_parser import parse_json_string
10
10
  from kiln_ai.adapters.parsers.parser_registry import model_parser_from_id
11
+ from kiln_ai.adapters.parsers.request_formatters import request_formatter_from_id
11
12
  from kiln_ai.adapters.prompt_builders import prompt_builder_from_id
12
13
  from kiln_ai.adapters.provider_tools import kiln_model_provider_from
13
14
  from kiln_ai.adapters.run_output import RunOutput
14
- from kiln_ai.datamodel import DataSource, DataSourceType, Task, TaskOutput, TaskRun
15
+ from kiln_ai.datamodel import (
16
+ DataSource,
17
+ DataSourceType,
18
+ Task,
19
+ TaskOutput,
20
+ TaskRun,
21
+ Usage,
22
+ )
15
23
  from kiln_ai.datamodel.json_schema import validate_schema_with_value_error
16
24
  from kiln_ai.datamodel.task import RunConfig
17
25
  from kiln_ai.utils.config import Config
@@ -106,14 +114,19 @@ class BaseAdapter(metaclass=ABCMeta):
106
114
  "This task requires a specific input schema. While the model produced JSON, that JSON didn't meet the schema. Search 'Troubleshooting Structured Data Issues' in our docs for more information.",
107
115
  )
108
116
 
117
+ # Format model input for model call (we save the original input in the task without formatting)
118
+ formatted_input = input
119
+ formatter_id = self.model_provider().formatter
120
+ if formatter_id is not None:
121
+ formatter = request_formatter_from_id(formatter_id)
122
+ formatted_input = formatter.format_input(input)
123
+
109
124
  # Run
110
- run_output = await self._run(input)
125
+ run_output, usage = await self._run(formatted_input)
111
126
 
112
127
  # Parse
113
128
  provider = self.model_provider()
114
- parser = model_parser_from_id(provider.parser)(
115
- structured_output=self.has_structured_output()
116
- )
129
+ parser = model_parser_from_id(provider.parser)
117
130
  parsed_output = parser.parse_output(original_output=run_output)
118
131
 
119
132
  # validate output
@@ -147,7 +160,7 @@ class BaseAdapter(metaclass=ABCMeta):
147
160
  )
148
161
 
149
162
  # Generate the run and output
150
- run = self.generate_run(input, input_source, parsed_output)
163
+ run = self.generate_run(input, input_source, parsed_output, usage)
151
164
 
152
165
  # Save the run if configured to do so, and we have a path to save to
153
166
  if (
@@ -170,7 +183,7 @@ class BaseAdapter(metaclass=ABCMeta):
170
183
  pass
171
184
 
172
185
  @abstractmethod
173
- async def _run(self, input: Dict | str) -> RunOutput:
186
+ async def _run(self, input: Dict | str) -> Tuple[RunOutput, Usage | None]:
174
187
  pass
175
188
 
176
189
  def build_prompt(self) -> str:
@@ -209,7 +222,11 @@ class BaseAdapter(metaclass=ABCMeta):
209
222
 
210
223
  # create a run and task output
211
224
  def generate_run(
212
- self, input: Dict | str, input_source: DataSource | None, run_output: RunOutput
225
+ self,
226
+ input: Dict | str,
227
+ input_source: DataSource | None,
228
+ run_output: RunOutput,
229
+ usage: Usage | None = None,
213
230
  ) -> TaskRun:
214
231
  # Convert input and output to JSON strings if they are dictionaries
215
232
  input_str = (
@@ -242,6 +259,7 @@ class BaseAdapter(metaclass=ABCMeta):
242
259
  ),
243
260
  intermediate_outputs=run_output.intermediate_outputs,
244
261
  tags=self.base_adapter_config.default_tags or [],
262
+ usage=usage,
245
263
  )
246
264
 
247
265
  return new_task_run