kiln-ai 0.15.0__py3-none-any.whl → 0.17.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.

Potentially problematic release.


This version of kiln-ai might be problematic. Click here for more details.

Files changed (72) hide show
  1. kiln_ai/adapters/__init__.py +2 -0
  2. kiln_ai/adapters/adapter_registry.py +22 -44
  3. kiln_ai/adapters/chat/__init__.py +8 -0
  4. kiln_ai/adapters/chat/chat_formatter.py +234 -0
  5. kiln_ai/adapters/chat/test_chat_formatter.py +131 -0
  6. kiln_ai/adapters/data_gen/test_data_gen_task.py +19 -6
  7. kiln_ai/adapters/eval/base_eval.py +8 -6
  8. kiln_ai/adapters/eval/eval_runner.py +9 -65
  9. kiln_ai/adapters/eval/g_eval.py +26 -8
  10. kiln_ai/adapters/eval/test_base_eval.py +166 -15
  11. kiln_ai/adapters/eval/test_eval_runner.py +3 -0
  12. kiln_ai/adapters/eval/test_g_eval.py +1 -0
  13. kiln_ai/adapters/fine_tune/base_finetune.py +2 -2
  14. kiln_ai/adapters/fine_tune/dataset_formatter.py +153 -197
  15. kiln_ai/adapters/fine_tune/test_base_finetune.py +10 -10
  16. kiln_ai/adapters/fine_tune/test_dataset_formatter.py +402 -211
  17. kiln_ai/adapters/fine_tune/test_fireworks_tinetune.py +3 -3
  18. kiln_ai/adapters/fine_tune/test_openai_finetune.py +6 -6
  19. kiln_ai/adapters/fine_tune/test_together_finetune.py +1 -0
  20. kiln_ai/adapters/fine_tune/test_vertex_finetune.py +4 -4
  21. kiln_ai/adapters/fine_tune/together_finetune.py +12 -1
  22. kiln_ai/adapters/ml_model_list.py +556 -45
  23. kiln_ai/adapters/model_adapters/base_adapter.py +100 -35
  24. kiln_ai/adapters/model_adapters/litellm_adapter.py +116 -100
  25. kiln_ai/adapters/model_adapters/litellm_config.py +3 -2
  26. kiln_ai/adapters/model_adapters/test_base_adapter.py +299 -52
  27. kiln_ai/adapters/model_adapters/test_litellm_adapter.py +121 -22
  28. kiln_ai/adapters/model_adapters/test_saving_adapter_results.py +44 -2
  29. kiln_ai/adapters/model_adapters/test_structured_output.py +48 -18
  30. kiln_ai/adapters/parsers/base_parser.py +0 -3
  31. kiln_ai/adapters/parsers/parser_registry.py +5 -3
  32. kiln_ai/adapters/parsers/r1_parser.py +17 -2
  33. kiln_ai/adapters/parsers/request_formatters.py +40 -0
  34. kiln_ai/adapters/parsers/test_parser_registry.py +2 -2
  35. kiln_ai/adapters/parsers/test_r1_parser.py +44 -1
  36. kiln_ai/adapters/parsers/test_request_formatters.py +76 -0
  37. kiln_ai/adapters/prompt_builders.py +14 -17
  38. kiln_ai/adapters/provider_tools.py +39 -4
  39. kiln_ai/adapters/repair/test_repair_task.py +27 -5
  40. kiln_ai/adapters/test_adapter_registry.py +88 -28
  41. kiln_ai/adapters/test_ml_model_list.py +158 -0
  42. kiln_ai/adapters/test_prompt_adaptors.py +17 -3
  43. kiln_ai/adapters/test_prompt_builders.py +27 -19
  44. kiln_ai/adapters/test_provider_tools.py +130 -12
  45. kiln_ai/datamodel/__init__.py +2 -2
  46. kiln_ai/datamodel/datamodel_enums.py +43 -4
  47. kiln_ai/datamodel/dataset_filters.py +69 -1
  48. kiln_ai/datamodel/dataset_split.py +4 -0
  49. kiln_ai/datamodel/eval.py +8 -0
  50. kiln_ai/datamodel/finetune.py +13 -7
  51. kiln_ai/datamodel/prompt_id.py +1 -0
  52. kiln_ai/datamodel/task.py +68 -7
  53. kiln_ai/datamodel/task_output.py +1 -1
  54. kiln_ai/datamodel/task_run.py +39 -7
  55. kiln_ai/datamodel/test_basemodel.py +5 -8
  56. kiln_ai/datamodel/test_dataset_filters.py +82 -0
  57. kiln_ai/datamodel/test_dataset_split.py +2 -8
  58. kiln_ai/datamodel/test_example_models.py +54 -0
  59. kiln_ai/datamodel/test_models.py +80 -9
  60. kiln_ai/datamodel/test_task.py +168 -2
  61. kiln_ai/utils/async_job_runner.py +106 -0
  62. kiln_ai/utils/config.py +3 -2
  63. kiln_ai/utils/dataset_import.py +81 -19
  64. kiln_ai/utils/logging.py +165 -0
  65. kiln_ai/utils/test_async_job_runner.py +199 -0
  66. kiln_ai/utils/test_config.py +23 -0
  67. kiln_ai/utils/test_dataset_import.py +272 -10
  68. {kiln_ai-0.15.0.dist-info → kiln_ai-0.17.0.dist-info}/METADATA +1 -1
  69. kiln_ai-0.17.0.dist-info/RECORD +113 -0
  70. kiln_ai-0.15.0.dist-info/RECORD +0 -104
  71. {kiln_ai-0.15.0.dist-info → kiln_ai-0.17.0.dist-info}/WHEEL +0 -0
  72. {kiln_ai-0.15.0.dist-info → kiln_ai-0.17.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -3,7 +3,11 @@ from typing import Dict, List, Literal
3
3
 
4
4
  from pydantic import BaseModel
5
5
 
6
- from kiln_ai.datamodel import StructuredOutputMode
6
+ from kiln_ai.datamodel.datamodel_enums import (
7
+ ChatStrategy,
8
+ ModelProviderName,
9
+ StructuredOutputMode,
10
+ )
7
11
 
8
12
  """
9
13
  Provides model configuration and management for various LLM providers and models.
@@ -12,28 +16,6 @@ including configuration, validation, and instantiation of language models.
12
16
  """
13
17
 
14
18
 
15
- class ModelProviderName(str, Enum):
16
- """
17
- Enumeration of supported AI model providers.
18
- """
19
-
20
- openai = "openai"
21
- groq = "groq"
22
- amazon_bedrock = "amazon_bedrock"
23
- ollama = "ollama"
24
- openrouter = "openrouter"
25
- fireworks_ai = "fireworks_ai"
26
- kiln_fine_tune = "kiln_fine_tune"
27
- kiln_custom_registry = "kiln_custom_registry"
28
- openai_compatible = "openai_compatible"
29
- anthropic = "anthropic"
30
- gemini_api = "gemini_api"
31
- azure_openai = "azure_openai"
32
- huggingface = "huggingface"
33
- vertex = "vertex"
34
- together_ai = "together_ai"
35
-
36
-
37
19
  class ModelFamily(str, Enum):
38
20
  """
39
21
  Enumeration of supported model families/architectures.
@@ -102,6 +84,8 @@ class ModelName(str, Enum):
102
84
  claude_3_5_sonnet = "claude_3_5_sonnet"
103
85
  claude_3_7_sonnet = "claude_3_7_sonnet"
104
86
  claude_3_7_sonnet_thinking = "claude_3_7_sonnet_thinking"
87
+ claude_sonnet_4 = "claude_sonnet_4"
88
+ claude_opus_4 = "claude_opus_4"
105
89
  gemini_1_5_flash = "gemini_1_5_flash"
106
90
  gemini_1_5_flash_8b = "gemini_1_5_flash_8b"
107
91
  gemini_1_5_pro = "gemini_1_5_pro"
@@ -126,6 +110,22 @@ class ModelName(str, Enum):
126
110
  deepseek_r1_distill_llama_8b = "deepseek_r1_distill_llama_8b"
127
111
  dolphin_2_9_8x22b = "dolphin_2_9_8x22b"
128
112
  grok_2 = "grok_2"
113
+ qwen_3_0p6b = "qwen_3_0p6b"
114
+ qwen_3_0p6b_no_thinking = "qwen_3_0p6b_no_thinking"
115
+ qwen_3_1p7b = "qwen_3_1p7b"
116
+ qwen_3_1p7b_no_thinking = "qwen_3_1p7b_no_thinking"
117
+ qwen_3_4b = "qwen_3_4b"
118
+ qwen_3_4b_no_thinking = "qwen_3_4b_no_thinking"
119
+ qwen_3_8b = "qwen_3_8b"
120
+ qwen_3_8b_no_thinking = "qwen_3_8b_no_thinking"
121
+ qwen_3_14b = "qwen_3_14b"
122
+ qwen_3_14b_no_thinking = "qwen_3_14b_no_thinking"
123
+ qwen_3_30b_a3b = "qwen_3_30b_a3b"
124
+ qwen_3_30b_a3b_no_thinking = "qwen_3_30b_a3b_no_thinking"
125
+ qwen_3_32b = "qwen_3_32b"
126
+ qwen_3_32b_no_thinking = "qwen_3_32b_no_thinking"
127
+ qwen_3_235b_a22b = "qwen_3_235b_a22b"
128
+ qwen_3_235b_a22b_no_thinking = "qwen_3_235b_a22b_no_thinking"
129
129
 
130
130
 
131
131
  class ModelParserID(str, Enum):
@@ -134,6 +134,15 @@ class ModelParserID(str, Enum):
134
134
  """
135
135
 
136
136
  r1_thinking = "r1_thinking"
137
+ optional_r1_thinking = "optional_r1_thinking"
138
+
139
+
140
+ class ModelFormatterID(str, Enum):
141
+ """
142
+ Enumeration of supported model formatters.
143
+ """
144
+
145
+ qwen3_style_no_think = "qwen3_style_no_think"
137
146
 
138
147
 
139
148
  class KilnModelProvider(BaseModel):
@@ -149,18 +158,23 @@ class KilnModelProvider(BaseModel):
149
158
  structured_output_mode: The mode we should use to call the model for structured output, if it was trained with structured output.
150
159
  parser: A parser to use for the model, if applicable
151
160
  reasoning_capable: Whether the model is designed to output thinking in a structured format (eg <think></think>). If so we don't use COT across 2 calls, and ask for thinking and final response in the same call.
161
+ tuned_chat_strategy: Used when a model is finetuned with a specific chat strategy, and it's best to use it at call time.
152
162
  """
153
163
 
154
164
  name: ModelProviderName
155
165
  model_id: str | None = None
156
166
  supports_structured_output: bool = True
157
167
  supports_data_gen: bool = True
168
+ suggested_for_data_gen: bool = False
158
169
  untested_model: bool = False
159
170
  provider_finetune_id: str | None = None
160
171
  structured_output_mode: StructuredOutputMode = StructuredOutputMode.default
161
172
  parser: ModelParserID | None = None
173
+ formatter: ModelFormatterID | None = None
162
174
  reasoning_capable: bool = False
163
175
  supports_logprobs: bool = False
176
+ suggested_for_evals: bool = False
177
+ tuned_chat_strategy: ChatStrategy | None = None
164
178
 
165
179
  # TODO P1: Need a more generalized way to handle custom provider parameters.
166
180
  # Making them quite declarative here for now, isolating provider specific logic
@@ -205,16 +219,22 @@ built_in_models: List[KilnModel] = [
205
219
  provider_finetune_id="gpt-4.1-2025-04-14",
206
220
  structured_output_mode=StructuredOutputMode.json_schema,
207
221
  supports_logprobs=True,
222
+ suggested_for_data_gen=True,
223
+ suggested_for_evals=True,
208
224
  ),
209
225
  KilnModelProvider(
210
226
  name=ModelProviderName.openrouter,
211
227
  model_id="openai/gpt-4.1",
212
228
  structured_output_mode=StructuredOutputMode.json_schema,
213
229
  supports_logprobs=True,
230
+ suggested_for_data_gen=True,
231
+ suggested_for_evals=True,
214
232
  ),
215
233
  KilnModelProvider(
216
234
  name=ModelProviderName.azure_openai,
217
235
  model_id="gpt-4.1",
236
+ suggested_for_data_gen=True,
237
+ suggested_for_evals=True,
218
238
  ),
219
239
  ],
220
240
  ),
@@ -230,16 +250,22 @@ built_in_models: List[KilnModel] = [
230
250
  provider_finetune_id="gpt-4.1-mini-2025-04-14",
231
251
  structured_output_mode=StructuredOutputMode.json_schema,
232
252
  supports_logprobs=True,
253
+ suggested_for_data_gen=True,
254
+ suggested_for_evals=True,
233
255
  ),
234
256
  KilnModelProvider(
235
257
  name=ModelProviderName.openrouter,
236
258
  model_id="openai/gpt-4.1-mini",
237
259
  structured_output_mode=StructuredOutputMode.json_schema,
238
260
  supports_logprobs=True,
261
+ suggested_for_data_gen=True,
262
+ suggested_for_evals=True,
239
263
  ),
240
264
  KilnModelProvider(
241
265
  name=ModelProviderName.azure_openai,
242
266
  model_id="gpt-4.1-mini",
267
+ suggested_for_data_gen=True,
268
+ suggested_for_evals=True,
243
269
  ),
244
270
  ],
245
271
  ),
@@ -625,11 +651,13 @@ built_in_models: List[KilnModel] = [
625
651
  name=ModelProviderName.openrouter,
626
652
  structured_output_mode=StructuredOutputMode.function_calling,
627
653
  model_id="anthropic/claude-3.7-sonnet",
654
+ suggested_for_data_gen=True,
628
655
  ),
629
656
  KilnModelProvider(
630
657
  name=ModelProviderName.anthropic,
631
658
  model_id="claude-3-7-sonnet-20250219",
632
659
  structured_output_mode=StructuredOutputMode.function_calling,
660
+ suggested_for_data_gen=True,
633
661
  ),
634
662
  ],
635
663
  ),
@@ -656,6 +684,46 @@ built_in_models: List[KilnModel] = [
656
684
  ),
657
685
  ],
658
686
  ),
687
+ # Claude Sonnet 4
688
+ KilnModel(
689
+ family=ModelFamily.claude,
690
+ name=ModelName.claude_sonnet_4,
691
+ friendly_name="Claude Sonnet 4",
692
+ providers=[
693
+ KilnModelProvider(
694
+ name=ModelProviderName.openrouter,
695
+ model_id="anthropic/claude-sonnet-4",
696
+ structured_output_mode=StructuredOutputMode.function_calling,
697
+ suggested_for_data_gen=True,
698
+ suggested_for_evals=True,
699
+ ),
700
+ KilnModelProvider(
701
+ name=ModelProviderName.anthropic,
702
+ model_id="claude-sonnet-4-20250514",
703
+ structured_output_mode=StructuredOutputMode.function_calling,
704
+ suggested_for_data_gen=True,
705
+ suggested_for_evals=True,
706
+ ),
707
+ ],
708
+ ),
709
+ # Claude Opus 4
710
+ KilnModel(
711
+ family=ModelFamily.claude,
712
+ name=ModelName.claude_opus_4,
713
+ friendly_name="Claude Opus 4",
714
+ providers=[
715
+ KilnModelProvider(
716
+ name=ModelProviderName.openrouter,
717
+ model_id="anthropic/claude-opus-4",
718
+ structured_output_mode=StructuredOutputMode.function_calling,
719
+ ),
720
+ KilnModelProvider(
721
+ name=ModelProviderName.anthropic,
722
+ model_id="claude-opus-4-20250514",
723
+ structured_output_mode=StructuredOutputMode.function_calling,
724
+ ),
725
+ ],
726
+ ),
659
727
  # Gemini 2.5 Pro
660
728
  KilnModel(
661
729
  family=ModelFamily.gemini,
@@ -666,16 +734,22 @@ built_in_models: List[KilnModel] = [
666
734
  name=ModelProviderName.openrouter,
667
735
  model_id="google/gemini-2.5-pro-preview-03-25",
668
736
  structured_output_mode=StructuredOutputMode.json_schema,
737
+ suggested_for_data_gen=True,
738
+ suggested_for_evals=True,
669
739
  ),
670
740
  KilnModelProvider(
671
741
  name=ModelProviderName.gemini_api,
672
742
  model_id="gemini-2.5-pro-preview-03-25",
673
743
  structured_output_mode=StructuredOutputMode.json_schema,
744
+ suggested_for_data_gen=True,
745
+ suggested_for_evals=True,
674
746
  ),
675
747
  KilnModelProvider(
676
748
  name=ModelProviderName.vertex,
677
749
  model_id="gemini-2.5-pro-preview-03-25",
678
750
  structured_output_mode=StructuredOutputMode.json_schema,
751
+ suggested_for_data_gen=True,
752
+ suggested_for_evals=True,
679
753
  ),
680
754
  ],
681
755
  ),
@@ -870,7 +944,7 @@ built_in_models: List[KilnModel] = [
870
944
  model_id="meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
871
945
  supports_data_gen=False,
872
946
  structured_output_mode=StructuredOutputMode.function_calling_weak,
873
- provider_finetune_id="meta-llama/Meta-Llama-3.1-8B-Instruct",
947
+ provider_finetune_id="meta-llama/Meta-Llama-3.1-8B-Instruct-Reference",
874
948
  ),
875
949
  ],
876
950
  ),
@@ -889,8 +963,7 @@ built_in_models: List[KilnModel] = [
889
963
  KilnModelProvider(
890
964
  name=ModelProviderName.openrouter,
891
965
  supports_data_gen=False,
892
- # Need to not pass "strict=True" to the function call to get this to work with logprobs for some reason. Openrouter issue.
893
- structured_output_mode=StructuredOutputMode.function_calling_weak,
966
+ structured_output_mode=StructuredOutputMode.json_schema,
894
967
  model_id="meta-llama/llama-3.1-70b-instruct",
895
968
  supports_logprobs=True,
896
969
  logprobs_openrouter_options=True,
@@ -911,7 +984,7 @@ built_in_models: List[KilnModel] = [
911
984
  model_id="meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
912
985
  supports_data_gen=False,
913
986
  structured_output_mode=StructuredOutputMode.function_calling_weak,
914
- provider_finetune_id="meta-llama/Meta-Llama-3.1-70B-Instruct",
987
+ provider_finetune_id="meta-llama/Meta-Llama-3.1-70B-Instruct-Reference",
915
988
  ),
916
989
  ],
917
990
  ),
@@ -1018,10 +1091,6 @@ built_in_models: List[KilnModel] = [
1018
1091
  supports_structured_output=False,
1019
1092
  supports_data_gen=False,
1020
1093
  ),
1021
- KilnModelProvider(
1022
- name=ModelProviderName.together_ai,
1023
- provider_finetune_id="meta-llama/Llama-3.2-1B-Instruct",
1024
- ),
1025
1094
  ],
1026
1095
  ),
1027
1096
  # Llama 3.2 3B
@@ -1058,7 +1127,6 @@ built_in_models: List[KilnModel] = [
1058
1127
  model_id="meta-llama/Llama-3.2-3B-Instruct-Turbo",
1059
1128
  supports_structured_output=False,
1060
1129
  supports_data_gen=False,
1061
- provider_finetune_id="meta-llama/Llama-3.2-3B-Instruct",
1062
1130
  ),
1063
1131
  ],
1064
1132
  ),
@@ -1068,10 +1136,6 @@ built_in_models: List[KilnModel] = [
1068
1136
  name=ModelName.llama_3_2_11b,
1069
1137
  friendly_name="Llama 3.2 11B",
1070
1138
  providers=[
1071
- KilnModelProvider(
1072
- name=ModelProviderName.groq,
1073
- model_id="llama-3.2-11b-vision-preview",
1074
- ),
1075
1139
  KilnModelProvider(
1076
1140
  name=ModelProviderName.openrouter,
1077
1141
  # Best mode, but fails to often to enable without warning
@@ -1112,10 +1176,6 @@ built_in_models: List[KilnModel] = [
1112
1176
  name=ModelName.llama_3_2_90b,
1113
1177
  friendly_name="Llama 3.2 90B",
1114
1178
  providers=[
1115
- KilnModelProvider(
1116
- name=ModelProviderName.groq,
1117
- model_id="llama-3.2-90b-vision-preview",
1118
- ),
1119
1179
  KilnModelProvider(
1120
1180
  name=ModelProviderName.openrouter,
1121
1181
  structured_output_mode=StructuredOutputMode.json_instruction_and_object,
@@ -1388,11 +1448,6 @@ built_in_models: List[KilnModel] = [
1388
1448
  structured_output_mode=StructuredOutputMode.json_instruction_and_object,
1389
1449
  model_id="google/gemma-3-27b-it",
1390
1450
  ),
1391
- KilnModelProvider(
1392
- name=ModelProviderName.huggingface,
1393
- model_id="google/gemma-3-27b-it",
1394
- structured_output_mode=StructuredOutputMode.json_instructions,
1395
- ),
1396
1451
  ],
1397
1452
  ),
1398
1453
  # Mixtral 8x7B
@@ -1578,6 +1633,8 @@ built_in_models: List[KilnModel] = [
1578
1633
  reasoning_capable=True,
1579
1634
  r1_openrouter_options=True,
1580
1635
  require_openrouter_reasoning=True,
1636
+ suggested_for_data_gen=True,
1637
+ suggested_for_evals=True,
1581
1638
  ),
1582
1639
  KilnModelProvider(
1583
1640
  name=ModelProviderName.fireworks_ai,
@@ -1585,6 +1642,8 @@ built_in_models: List[KilnModel] = [
1585
1642
  parser=ModelParserID.r1_thinking,
1586
1643
  structured_output_mode=StructuredOutputMode.json_instructions,
1587
1644
  reasoning_capable=True,
1645
+ suggested_for_data_gen=True,
1646
+ suggested_for_evals=True,
1588
1647
  ),
1589
1648
  KilnModelProvider(
1590
1649
  # I want your RAM
@@ -1593,6 +1652,8 @@ built_in_models: List[KilnModel] = [
1593
1652
  parser=ModelParserID.r1_thinking,
1594
1653
  structured_output_mode=StructuredOutputMode.json_instructions,
1595
1654
  reasoning_capable=True,
1655
+ suggested_for_data_gen=True,
1656
+ suggested_for_evals=True,
1596
1657
  ),
1597
1658
  KilnModelProvider(
1598
1659
  name=ModelProviderName.together_ai,
@@ -1600,6 +1661,8 @@ built_in_models: List[KilnModel] = [
1600
1661
  structured_output_mode=StructuredOutputMode.json_instructions,
1601
1662
  parser=ModelParserID.r1_thinking,
1602
1663
  reasoning_capable=True,
1664
+ suggested_for_data_gen=True,
1665
+ suggested_for_evals=True,
1603
1666
  ),
1604
1667
  ],
1605
1668
  ),
@@ -1819,4 +1882,452 @@ built_in_models: List[KilnModel] = [
1819
1882
  ),
1820
1883
  ],
1821
1884
  ),
1885
+ # Qwen 3 0.6B
1886
+ KilnModel(
1887
+ family=ModelFamily.qwen,
1888
+ name=ModelName.qwen_3_0p6b,
1889
+ friendly_name="Qwen 3 0.6B",
1890
+ providers=[
1891
+ KilnModelProvider(
1892
+ name=ModelProviderName.openrouter,
1893
+ model_id="qwen/qwen3-0.6b-04-28:free",
1894
+ structured_output_mode=StructuredOutputMode.json_instructions,
1895
+ reasoning_capable=True,
1896
+ require_openrouter_reasoning=True,
1897
+ r1_openrouter_options=True,
1898
+ parser=ModelParserID.r1_thinking,
1899
+ supports_data_gen=False,
1900
+ ),
1901
+ KilnModelProvider(
1902
+ name=ModelProviderName.ollama,
1903
+ model_id="qwen3:0.6b",
1904
+ supports_data_gen=False,
1905
+ reasoning_capable=True,
1906
+ structured_output_mode=StructuredOutputMode.json_schema,
1907
+ ),
1908
+ ],
1909
+ ),
1910
+ # Qwen 3 0.6B Non-Thinking -- not respecting /no_think tag, skipping
1911
+ # Qwen 3 1.7B
1912
+ KilnModel(
1913
+ family=ModelFamily.qwen,
1914
+ name=ModelName.qwen_3_1p7b,
1915
+ friendly_name="Qwen 3 1.7B",
1916
+ providers=[
1917
+ KilnModelProvider(
1918
+ name=ModelProviderName.openrouter,
1919
+ model_id="qwen/qwen3-1.7b:free",
1920
+ structured_output_mode=StructuredOutputMode.json_instructions,
1921
+ reasoning_capable=True,
1922
+ require_openrouter_reasoning=True,
1923
+ r1_openrouter_options=True,
1924
+ parser=ModelParserID.r1_thinking,
1925
+ supports_data_gen=False,
1926
+ ),
1927
+ KilnModelProvider(
1928
+ name=ModelProviderName.ollama,
1929
+ model_id="qwen3:1.7b",
1930
+ supports_data_gen=False,
1931
+ reasoning_capable=True,
1932
+ structured_output_mode=StructuredOutputMode.json_schema,
1933
+ ),
1934
+ ],
1935
+ ),
1936
+ # Qwen 3 1.7B Non-Thinking
1937
+ KilnModel(
1938
+ family=ModelFamily.qwen,
1939
+ name=ModelName.qwen_3_1p7b_no_thinking,
1940
+ friendly_name="Qwen 3 1.7B Non-Thinking",
1941
+ providers=[
1942
+ KilnModelProvider(
1943
+ name=ModelProviderName.openrouter,
1944
+ model_id="qwen/qwen3-1.7b:free",
1945
+ structured_output_mode=StructuredOutputMode.json_instructions,
1946
+ formatter=ModelFormatterID.qwen3_style_no_think,
1947
+ supports_data_gen=False,
1948
+ parser=ModelParserID.optional_r1_thinking,
1949
+ ),
1950
+ KilnModelProvider(
1951
+ name=ModelProviderName.ollama,
1952
+ model_id="qwen3:1.7b",
1953
+ formatter=ModelFormatterID.qwen3_style_no_think,
1954
+ supports_data_gen=False,
1955
+ structured_output_mode=StructuredOutputMode.json_schema,
1956
+ ),
1957
+ ],
1958
+ ),
1959
+ # Qwen 3 4B
1960
+ KilnModel(
1961
+ family=ModelFamily.qwen,
1962
+ name=ModelName.qwen_3_4b,
1963
+ friendly_name="Qwen 3 4B",
1964
+ providers=[
1965
+ KilnModelProvider(
1966
+ name=ModelProviderName.openrouter,
1967
+ model_id="qwen/qwen3-4b:free",
1968
+ structured_output_mode=StructuredOutputMode.json_instructions,
1969
+ reasoning_capable=True,
1970
+ require_openrouter_reasoning=True,
1971
+ r1_openrouter_options=True,
1972
+ parser=ModelParserID.r1_thinking,
1973
+ supports_data_gen=False,
1974
+ ),
1975
+ KilnModelProvider(
1976
+ name=ModelProviderName.ollama,
1977
+ model_id="qwen3:4b",
1978
+ supports_data_gen=False,
1979
+ reasoning_capable=True,
1980
+ structured_output_mode=StructuredOutputMode.json_schema,
1981
+ ),
1982
+ ],
1983
+ ),
1984
+ # Qwen 3 4B Non-Thinking
1985
+ KilnModel(
1986
+ family=ModelFamily.qwen,
1987
+ name=ModelName.qwen_3_4b_no_thinking,
1988
+ friendly_name="Qwen 3 4B Non-Thinking",
1989
+ providers=[
1990
+ KilnModelProvider(
1991
+ name=ModelProviderName.openrouter,
1992
+ model_id="qwen/qwen3-4b:free",
1993
+ structured_output_mode=StructuredOutputMode.json_instructions,
1994
+ formatter=ModelFormatterID.qwen3_style_no_think,
1995
+ supports_data_gen=False,
1996
+ parser=ModelParserID.optional_r1_thinking,
1997
+ ),
1998
+ KilnModelProvider(
1999
+ name=ModelProviderName.ollama,
2000
+ model_id="qwen3:4b",
2001
+ structured_output_mode=StructuredOutputMode.json_schema,
2002
+ formatter=ModelFormatterID.qwen3_style_no_think,
2003
+ supports_data_gen=False,
2004
+ ),
2005
+ ],
2006
+ ),
2007
+ # Qwen 3 8B
2008
+ KilnModel(
2009
+ family=ModelFamily.qwen,
2010
+ name=ModelName.qwen_3_8b,
2011
+ friendly_name="Qwen 3 8B",
2012
+ providers=[
2013
+ KilnModelProvider(
2014
+ name=ModelProviderName.openrouter,
2015
+ model_id="qwen/qwen3-8b",
2016
+ supports_structured_output=True,
2017
+ structured_output_mode=StructuredOutputMode.json_instructions,
2018
+ reasoning_capable=True,
2019
+ require_openrouter_reasoning=True,
2020
+ r1_openrouter_options=True,
2021
+ parser=ModelParserID.r1_thinking,
2022
+ supports_data_gen=False,
2023
+ ),
2024
+ KilnModelProvider(
2025
+ name=ModelProviderName.ollama,
2026
+ model_id="qwen3:8b",
2027
+ supports_data_gen=False,
2028
+ reasoning_capable=True,
2029
+ structured_output_mode=StructuredOutputMode.json_schema,
2030
+ ),
2031
+ ],
2032
+ ),
2033
+ # Qwen 3 8B Non-Thinking
2034
+ KilnModel(
2035
+ family=ModelFamily.qwen,
2036
+ name=ModelName.qwen_3_8b_no_thinking,
2037
+ friendly_name="Qwen 3 8B Non-Thinking",
2038
+ providers=[
2039
+ KilnModelProvider(
2040
+ name=ModelProviderName.openrouter,
2041
+ model_id="qwen/qwen3-8b",
2042
+ structured_output_mode=StructuredOutputMode.json_instructions,
2043
+ formatter=ModelFormatterID.qwen3_style_no_think,
2044
+ supports_data_gen=False,
2045
+ parser=ModelParserID.optional_r1_thinking,
2046
+ ),
2047
+ KilnModelProvider(
2048
+ name=ModelProviderName.ollama,
2049
+ model_id="qwen3:8b",
2050
+ structured_output_mode=StructuredOutputMode.json_schema,
2051
+ formatter=ModelFormatterID.qwen3_style_no_think,
2052
+ supports_data_gen=False,
2053
+ ),
2054
+ ],
2055
+ ),
2056
+ # Qwen 3 14B
2057
+ KilnModel(
2058
+ family=ModelFamily.qwen,
2059
+ name=ModelName.qwen_3_14b,
2060
+ friendly_name="Qwen 3 14B",
2061
+ providers=[
2062
+ KilnModelProvider(
2063
+ name=ModelProviderName.openrouter,
2064
+ model_id="qwen/qwen3-14b",
2065
+ structured_output_mode=StructuredOutputMode.json_instructions,
2066
+ reasoning_capable=True,
2067
+ require_openrouter_reasoning=True,
2068
+ r1_openrouter_options=True,
2069
+ parser=ModelParserID.r1_thinking,
2070
+ supports_data_gen=True,
2071
+ ),
2072
+ KilnModelProvider(
2073
+ name=ModelProviderName.ollama,
2074
+ model_id="qwen3:14b",
2075
+ supports_data_gen=True,
2076
+ reasoning_capable=True,
2077
+ structured_output_mode=StructuredOutputMode.json_schema,
2078
+ ),
2079
+ ],
2080
+ ),
2081
+ # Qwen 3 14B Non-Thinking
2082
+ KilnModel(
2083
+ family=ModelFamily.qwen,
2084
+ name=ModelName.qwen_3_14b_no_thinking,
2085
+ friendly_name="Qwen 3 14B Non-Thinking",
2086
+ providers=[
2087
+ KilnModelProvider(
2088
+ name=ModelProviderName.openrouter,
2089
+ model_id="qwen/qwen3-14b",
2090
+ structured_output_mode=StructuredOutputMode.json_instructions,
2091
+ formatter=ModelFormatterID.qwen3_style_no_think,
2092
+ supports_data_gen=True,
2093
+ parser=ModelParserID.optional_r1_thinking,
2094
+ ),
2095
+ KilnModelProvider(
2096
+ name=ModelProviderName.ollama,
2097
+ model_id="qwen3:14b",
2098
+ formatter=ModelFormatterID.qwen3_style_no_think,
2099
+ supports_data_gen=True,
2100
+ structured_output_mode=StructuredOutputMode.json_schema,
2101
+ ),
2102
+ ],
2103
+ ),
2104
+ # Qwen 3 30B (3B Active)
2105
+ KilnModel(
2106
+ family=ModelFamily.qwen,
2107
+ name=ModelName.qwen_3_30b_a3b,
2108
+ friendly_name="Qwen 3 30B (3B Active)",
2109
+ providers=[
2110
+ KilnModelProvider(
2111
+ name=ModelProviderName.openrouter,
2112
+ model_id="qwen/qwen3-30b-a3b",
2113
+ structured_output_mode=StructuredOutputMode.json_instructions,
2114
+ reasoning_capable=True,
2115
+ require_openrouter_reasoning=True,
2116
+ r1_openrouter_options=True,
2117
+ parser=ModelParserID.r1_thinking,
2118
+ supports_data_gen=True,
2119
+ ),
2120
+ KilnModelProvider(
2121
+ name=ModelProviderName.ollama,
2122
+ model_id="qwen3:30b-a3b",
2123
+ supports_data_gen=True,
2124
+ reasoning_capable=True,
2125
+ structured_output_mode=StructuredOutputMode.json_schema,
2126
+ ),
2127
+ KilnModelProvider(
2128
+ name=ModelProviderName.fireworks_ai,
2129
+ model_id="accounts/fireworks/models/qwen3-30b-a3b",
2130
+ supports_data_gen=True,
2131
+ reasoning_capable=True,
2132
+ structured_output_mode=StructuredOutputMode.json_instructions,
2133
+ parser=ModelParserID.r1_thinking,
2134
+ ),
2135
+ ],
2136
+ ),
2137
+ # Qwen 3 30B (3B Active) Non-Thinking
2138
+ KilnModel(
2139
+ family=ModelFamily.qwen,
2140
+ name=ModelName.qwen_3_30b_a3b_no_thinking,
2141
+ friendly_name="Qwen 3 30B (3B Active) Non-Thinking",
2142
+ providers=[
2143
+ KilnModelProvider(
2144
+ name=ModelProviderName.openrouter,
2145
+ model_id="qwen/qwen3-30b-a3b",
2146
+ structured_output_mode=StructuredOutputMode.json_instructions,
2147
+ formatter=ModelFormatterID.qwen3_style_no_think,
2148
+ supports_data_gen=True,
2149
+ parser=ModelParserID.optional_r1_thinking,
2150
+ ),
2151
+ KilnModelProvider(
2152
+ name=ModelProviderName.ollama,
2153
+ model_id="qwen3:30b-a3b",
2154
+ structured_output_mode=StructuredOutputMode.json_schema,
2155
+ formatter=ModelFormatterID.qwen3_style_no_think,
2156
+ supports_data_gen=True,
2157
+ ),
2158
+ KilnModelProvider(
2159
+ name=ModelProviderName.fireworks_ai,
2160
+ model_id="accounts/fireworks/models/qwen3-30b-a3b",
2161
+ supports_data_gen=True,
2162
+ formatter=ModelFormatterID.qwen3_style_no_think,
2163
+ structured_output_mode=StructuredOutputMode.json_instructions,
2164
+ parser=ModelParserID.optional_r1_thinking,
2165
+ ),
2166
+ ],
2167
+ ),
2168
+ # Qwen 3 32B
2169
+ KilnModel(
2170
+ family=ModelFamily.qwen,
2171
+ name=ModelName.qwen_3_32b,
2172
+ friendly_name="Qwen 3 32B",
2173
+ providers=[
2174
+ KilnModelProvider(
2175
+ name=ModelProviderName.openrouter,
2176
+ model_id="qwen/qwen3-32b",
2177
+ reasoning_capable=True,
2178
+ require_openrouter_reasoning=True,
2179
+ r1_openrouter_options=True,
2180
+ structured_output_mode=StructuredOutputMode.json_instructions,
2181
+ parser=ModelParserID.r1_thinking,
2182
+ supports_data_gen=True,
2183
+ ),
2184
+ KilnModelProvider(
2185
+ name=ModelProviderName.ollama,
2186
+ model_id="qwen3:32b",
2187
+ supports_data_gen=True,
2188
+ reasoning_capable=True,
2189
+ structured_output_mode=StructuredOutputMode.json_schema,
2190
+ ),
2191
+ ],
2192
+ ),
2193
+ # Qwen 3 32B No Thinking
2194
+ KilnModel(
2195
+ family=ModelFamily.qwen,
2196
+ name=ModelName.qwen_3_32b_no_thinking,
2197
+ friendly_name="Qwen 3 32B Non-Thinking",
2198
+ providers=[
2199
+ KilnModelProvider(
2200
+ name=ModelProviderName.openrouter,
2201
+ model_id="qwen/qwen3-32b",
2202
+ structured_output_mode=StructuredOutputMode.json_instructions,
2203
+ formatter=ModelFormatterID.qwen3_style_no_think,
2204
+ supports_data_gen=True,
2205
+ parser=ModelParserID.optional_r1_thinking,
2206
+ ),
2207
+ KilnModelProvider(
2208
+ name=ModelProviderName.ollama,
2209
+ model_id="qwen3:32b",
2210
+ structured_output_mode=StructuredOutputMode.json_schema,
2211
+ formatter=ModelFormatterID.qwen3_style_no_think,
2212
+ supports_data_gen=True,
2213
+ ),
2214
+ ],
2215
+ ),
2216
+ # Qwen 3 235B (22B Active)
2217
+ KilnModel(
2218
+ family=ModelFamily.qwen,
2219
+ name=ModelName.qwen_3_235b_a22b,
2220
+ friendly_name="Qwen 3 235B (22B Active)",
2221
+ providers=[
2222
+ KilnModelProvider(
2223
+ name=ModelProviderName.openrouter,
2224
+ model_id="qwen/qwen3-235b-a22b",
2225
+ reasoning_capable=True,
2226
+ require_openrouter_reasoning=True,
2227
+ supports_data_gen=True,
2228
+ suggested_for_data_gen=True,
2229
+ r1_openrouter_options=True,
2230
+ structured_output_mode=StructuredOutputMode.json_instructions,
2231
+ parser=ModelParserID.r1_thinking,
2232
+ ),
2233
+ KilnModelProvider(
2234
+ name=ModelProviderName.ollama,
2235
+ model_id="qwen3:235b-a22b",
2236
+ supports_data_gen=True,
2237
+ reasoning_capable=True,
2238
+ structured_output_mode=StructuredOutputMode.json_schema,
2239
+ ),
2240
+ KilnModelProvider(
2241
+ name=ModelProviderName.fireworks_ai,
2242
+ model_id="accounts/fireworks/models/qwen3-235b-a22b",
2243
+ supports_data_gen=True,
2244
+ reasoning_capable=True,
2245
+ structured_output_mode=StructuredOutputMode.json_instructions,
2246
+ parser=ModelParserID.r1_thinking,
2247
+ ),
2248
+ KilnModelProvider(
2249
+ name=ModelProviderName.together_ai,
2250
+ model_id="Qwen/Qwen3-235B-A22B-fp8-tput",
2251
+ supports_data_gen=True,
2252
+ reasoning_capable=True,
2253
+ structured_output_mode=StructuredOutputMode.json_instructions,
2254
+ parser=ModelParserID.r1_thinking,
2255
+ ),
2256
+ ],
2257
+ ),
2258
+ # Qwen 3 235B (22B Active) Non-Thinking
2259
+ KilnModel(
2260
+ family=ModelFamily.qwen,
2261
+ name=ModelName.qwen_3_235b_a22b_no_thinking,
2262
+ friendly_name="Qwen 3 235B (22B Active) Non-Thinking",
2263
+ providers=[
2264
+ KilnModelProvider(
2265
+ name=ModelProviderName.openrouter,
2266
+ model_id="qwen/qwen3-235b-a22b",
2267
+ structured_output_mode=StructuredOutputMode.json_instructions,
2268
+ formatter=ModelFormatterID.qwen3_style_no_think,
2269
+ supports_data_gen=True,
2270
+ reasoning_capable=False,
2271
+ parser=ModelParserID.optional_r1_thinking,
2272
+ ),
2273
+ KilnModelProvider(
2274
+ name=ModelProviderName.ollama,
2275
+ model_id="qwen3:235b-a22b",
2276
+ structured_output_mode=StructuredOutputMode.json_schema,
2277
+ formatter=ModelFormatterID.qwen3_style_no_think,
2278
+ supports_data_gen=True,
2279
+ ),
2280
+ KilnModelProvider(
2281
+ name=ModelProviderName.fireworks_ai,
2282
+ model_id="accounts/fireworks/models/qwen3-235b-a22b",
2283
+ supports_data_gen=True,
2284
+ formatter=ModelFormatterID.qwen3_style_no_think,
2285
+ structured_output_mode=StructuredOutputMode.json_instructions,
2286
+ parser=ModelParserID.optional_r1_thinking,
2287
+ ),
2288
+ KilnModelProvider(
2289
+ name=ModelProviderName.together_ai,
2290
+ model_id="Qwen/Qwen3-235B-A22B-fp8-tput",
2291
+ supports_data_gen=True,
2292
+ formatter=ModelFormatterID.qwen3_style_no_think,
2293
+ structured_output_mode=StructuredOutputMode.json_instructions,
2294
+ parser=ModelParserID.optional_r1_thinking,
2295
+ ),
2296
+ ],
2297
+ ),
1822
2298
  ]
2299
+
2300
+
2301
+ def get_model_by_name(name: ModelName) -> KilnModel:
2302
+ for model in built_in_models:
2303
+ if model.name == name:
2304
+ return model
2305
+ raise ValueError(f"Model {name} not found in the list of built-in models")
2306
+
2307
+
2308
+ def default_structured_output_mode_for_model_provider(
2309
+ model_name: str,
2310
+ provider: ModelProviderName,
2311
+ default: StructuredOutputMode = StructuredOutputMode.default,
2312
+ disallowed_modes: List[StructuredOutputMode] = [],
2313
+ ) -> StructuredOutputMode:
2314
+ """
2315
+ We don't expose setting this manually in the UI, so pull a recommended mode from ml_model_list
2316
+ """
2317
+ try:
2318
+ # Convert string to ModelName enum
2319
+ model_name_enum = ModelName(model_name)
2320
+ model = get_model_by_name(model_name_enum)
2321
+ except (ValueError, KeyError):
2322
+ # If model not found, return default
2323
+ return default
2324
+
2325
+ # Find the provider within the model's providers
2326
+ for model_provider in model.providers:
2327
+ if model_provider.name == provider:
2328
+ mode = model_provider.structured_output_mode
2329
+ if mode not in disallowed_modes:
2330
+ return mode
2331
+
2332
+ # If provider not found, return default
2333
+ return default