kiln-ai 0.8.1__py3-none-any.whl → 0.12.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.
- kiln_ai/adapters/__init__.py +7 -7
- kiln_ai/adapters/adapter_registry.py +81 -10
- kiln_ai/adapters/data_gen/data_gen_task.py +21 -3
- kiln_ai/adapters/data_gen/test_data_gen_task.py +23 -3
- kiln_ai/adapters/eval/base_eval.py +164 -0
- kiln_ai/adapters/eval/eval_runner.py +267 -0
- kiln_ai/adapters/eval/g_eval.py +367 -0
- kiln_ai/adapters/eval/registry.py +16 -0
- kiln_ai/adapters/eval/test_base_eval.py +324 -0
- kiln_ai/adapters/eval/test_eval_runner.py +640 -0
- kiln_ai/adapters/eval/test_g_eval.py +497 -0
- kiln_ai/adapters/eval/test_g_eval_data.py +4 -0
- kiln_ai/adapters/fine_tune/base_finetune.py +5 -1
- kiln_ai/adapters/fine_tune/dataset_formatter.py +310 -65
- kiln_ai/adapters/fine_tune/fireworks_finetune.py +47 -32
- kiln_ai/adapters/fine_tune/openai_finetune.py +12 -11
- kiln_ai/adapters/fine_tune/test_base_finetune.py +19 -0
- kiln_ai/adapters/fine_tune/test_dataset_formatter.py +472 -129
- kiln_ai/adapters/fine_tune/test_fireworks_tinetune.py +114 -22
- kiln_ai/adapters/fine_tune/test_openai_finetune.py +125 -14
- kiln_ai/adapters/ml_model_list.py +434 -93
- kiln_ai/adapters/model_adapters/__init__.py +18 -0
- kiln_ai/adapters/model_adapters/base_adapter.py +250 -0
- kiln_ai/adapters/model_adapters/langchain_adapters.py +309 -0
- kiln_ai/adapters/model_adapters/openai_compatible_config.py +10 -0
- kiln_ai/adapters/model_adapters/openai_model_adapter.py +289 -0
- kiln_ai/adapters/model_adapters/test_base_adapter.py +199 -0
- kiln_ai/adapters/{test_langchain_adapter.py → model_adapters/test_langchain_adapter.py} +105 -97
- kiln_ai/adapters/model_adapters/test_openai_model_adapter.py +216 -0
- kiln_ai/adapters/{test_saving_adapter_results.py → model_adapters/test_saving_adapter_results.py} +80 -30
- kiln_ai/adapters/{test_structured_output.py → model_adapters/test_structured_output.py} +125 -46
- kiln_ai/adapters/ollama_tools.py +0 -1
- kiln_ai/adapters/parsers/__init__.py +10 -0
- kiln_ai/adapters/parsers/base_parser.py +12 -0
- kiln_ai/adapters/parsers/json_parser.py +37 -0
- kiln_ai/adapters/parsers/parser_registry.py +19 -0
- kiln_ai/adapters/parsers/r1_parser.py +69 -0
- kiln_ai/adapters/parsers/test_json_parser.py +81 -0
- kiln_ai/adapters/parsers/test_parser_registry.py +32 -0
- kiln_ai/adapters/parsers/test_r1_parser.py +144 -0
- kiln_ai/adapters/prompt_builders.py +193 -49
- kiln_ai/adapters/provider_tools.py +91 -36
- kiln_ai/adapters/repair/repair_task.py +18 -19
- kiln_ai/adapters/repair/test_repair_task.py +7 -7
- kiln_ai/adapters/run_output.py +11 -0
- kiln_ai/adapters/test_adapter_registry.py +177 -0
- kiln_ai/adapters/test_generate_docs.py +69 -0
- kiln_ai/adapters/test_ollama_tools.py +0 -1
- kiln_ai/adapters/test_prompt_adaptors.py +25 -18
- kiln_ai/adapters/test_prompt_builders.py +265 -44
- kiln_ai/adapters/test_provider_tools.py +268 -46
- kiln_ai/datamodel/__init__.py +51 -772
- kiln_ai/datamodel/basemodel.py +31 -11
- kiln_ai/datamodel/datamodel_enums.py +58 -0
- kiln_ai/datamodel/dataset_filters.py +114 -0
- kiln_ai/datamodel/dataset_split.py +170 -0
- kiln_ai/datamodel/eval.py +298 -0
- kiln_ai/datamodel/finetune.py +105 -0
- kiln_ai/datamodel/json_schema.py +14 -3
- kiln_ai/datamodel/model_cache.py +8 -3
- kiln_ai/datamodel/project.py +23 -0
- kiln_ai/datamodel/prompt.py +37 -0
- kiln_ai/datamodel/prompt_id.py +83 -0
- kiln_ai/datamodel/strict_mode.py +24 -0
- kiln_ai/datamodel/task.py +181 -0
- kiln_ai/datamodel/task_output.py +321 -0
- kiln_ai/datamodel/task_run.py +164 -0
- kiln_ai/datamodel/test_basemodel.py +80 -2
- kiln_ai/datamodel/test_dataset_filters.py +71 -0
- kiln_ai/datamodel/test_dataset_split.py +127 -6
- kiln_ai/datamodel/test_datasource.py +3 -2
- kiln_ai/datamodel/test_eval_model.py +635 -0
- kiln_ai/datamodel/test_example_models.py +34 -17
- kiln_ai/datamodel/test_json_schema.py +23 -0
- kiln_ai/datamodel/test_model_cache.py +24 -0
- kiln_ai/datamodel/test_model_perf.py +125 -0
- kiln_ai/datamodel/test_models.py +131 -2
- kiln_ai/datamodel/test_prompt_id.py +129 -0
- kiln_ai/datamodel/test_task.py +159 -0
- kiln_ai/utils/config.py +6 -1
- kiln_ai/utils/exhaustive_error.py +6 -0
- {kiln_ai-0.8.1.dist-info → kiln_ai-0.12.0.dist-info}/METADATA +45 -7
- kiln_ai-0.12.0.dist-info/RECORD +100 -0
- kiln_ai/adapters/base_adapter.py +0 -191
- kiln_ai/adapters/langchain_adapters.py +0 -256
- kiln_ai-0.8.1.dist-info/RECORD +0 -58
- {kiln_ai-0.8.1.dist-info → kiln_ai-0.12.0.dist-info}/WHEEL +0 -0
- {kiln_ai-0.8.1.dist-info → kiln_ai-0.12.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pydantic import ValidationError
|
|
3
|
+
|
|
4
|
+
from kiln_ai.datamodel.datamodel_enums import TaskOutputRatingType
|
|
5
|
+
from kiln_ai.datamodel.prompt_id import PromptGenerators
|
|
6
|
+
from kiln_ai.datamodel.task import RunConfig, RunConfigProperties, Task, TaskRunConfig
|
|
7
|
+
from kiln_ai.datamodel.task_output import normalize_rating
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_runconfig_valid_creation():
|
|
11
|
+
task = Task(id="task1", name="Test Task", instruction="Do something")
|
|
12
|
+
|
|
13
|
+
config = RunConfig(
|
|
14
|
+
task=task,
|
|
15
|
+
model_name="gpt-4",
|
|
16
|
+
model_provider_name="openai",
|
|
17
|
+
prompt_id=PromptGenerators.SIMPLE,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
assert config.task == task
|
|
21
|
+
assert config.model_name == "gpt-4"
|
|
22
|
+
assert config.model_provider_name == "openai"
|
|
23
|
+
assert config.prompt_id == PromptGenerators.SIMPLE # Check default value
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_runconfig_missing_required_fields():
|
|
27
|
+
with pytest.raises(ValidationError) as exc_info:
|
|
28
|
+
RunConfig()
|
|
29
|
+
|
|
30
|
+
errors = exc_info.value.errors()
|
|
31
|
+
assert (
|
|
32
|
+
len(errors) == 4
|
|
33
|
+
) # task, model_name, model_provider_name, and prompt_id are required
|
|
34
|
+
assert any(error["loc"][0] == "task" for error in errors)
|
|
35
|
+
assert any(error["loc"][0] == "model_name" for error in errors)
|
|
36
|
+
assert any(error["loc"][0] == "model_provider_name" for error in errors)
|
|
37
|
+
assert any(error["loc"][0] == "prompt_id" for error in errors)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_runconfig_custom_prompt_id():
|
|
41
|
+
task = Task(id="task1", name="Test Task", instruction="Do something")
|
|
42
|
+
|
|
43
|
+
config = RunConfig(
|
|
44
|
+
task=task,
|
|
45
|
+
model_name="gpt-4",
|
|
46
|
+
model_provider_name="openai",
|
|
47
|
+
prompt_id=PromptGenerators.SIMPLE_CHAIN_OF_THOUGHT,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
assert config.prompt_id == PromptGenerators.SIMPLE_CHAIN_OF_THOUGHT
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@pytest.fixture
|
|
54
|
+
def sample_task():
|
|
55
|
+
return Task(name="Test Task", instruction="Test instruction")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.fixture
|
|
59
|
+
def sample_run_config_props(sample_task):
|
|
60
|
+
return RunConfigProperties(
|
|
61
|
+
model_name="gpt-4",
|
|
62
|
+
model_provider_name="openai",
|
|
63
|
+
prompt_id=PromptGenerators.SIMPLE,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_task_run_config_valid_creation(sample_task, sample_run_config_props):
|
|
68
|
+
config = TaskRunConfig(
|
|
69
|
+
name="Test Config",
|
|
70
|
+
description="Test description",
|
|
71
|
+
run_config_properties=sample_run_config_props,
|
|
72
|
+
parent=sample_task,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
assert config.name == "Test Config"
|
|
76
|
+
assert config.description == "Test description"
|
|
77
|
+
assert config.run_config_properties == sample_run_config_props
|
|
78
|
+
assert config.parent_task() == sample_task
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_task_run_config_minimal_creation(sample_task, sample_run_config_props):
|
|
82
|
+
# Test creation with only required fields
|
|
83
|
+
config = TaskRunConfig(
|
|
84
|
+
name="Test Config",
|
|
85
|
+
run_config_properties=sample_run_config_props,
|
|
86
|
+
parent=sample_task,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
assert config.name == "Test Config"
|
|
90
|
+
assert config.description is None
|
|
91
|
+
assert config.run_config_properties == sample_run_config_props
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_task_run_config_missing_required_fields(sample_task):
|
|
95
|
+
# Test missing name
|
|
96
|
+
with pytest.raises(ValidationError) as exc_info:
|
|
97
|
+
TaskRunConfig(
|
|
98
|
+
run_config_properties=RunConfigProperties(
|
|
99
|
+
task=sample_task, model_name="gpt-4", model_provider_name="openai"
|
|
100
|
+
),
|
|
101
|
+
parent=sample_task,
|
|
102
|
+
)
|
|
103
|
+
assert "Field required" in str(exc_info.value)
|
|
104
|
+
|
|
105
|
+
# Test missing run_config
|
|
106
|
+
with pytest.raises(ValidationError) as exc_info:
|
|
107
|
+
TaskRunConfig(name="Test Config", parent=sample_task)
|
|
108
|
+
assert "Field required" in str(exc_info.value)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_task_run_config_missing_task_in_run_config(sample_task):
|
|
112
|
+
with pytest.raises(
|
|
113
|
+
ValidationError, match="Input should be a valid dictionary or instance of Task"
|
|
114
|
+
):
|
|
115
|
+
# Create a run config without a task
|
|
116
|
+
RunConfig(
|
|
117
|
+
model_name="gpt-4",
|
|
118
|
+
model_provider_name="openai",
|
|
119
|
+
task=None, # type: ignore
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@pytest.mark.parametrize(
|
|
124
|
+
"rating_type,rating,expected",
|
|
125
|
+
[
|
|
126
|
+
(TaskOutputRatingType.five_star, 1, 0),
|
|
127
|
+
(TaskOutputRatingType.five_star, 2, 0.25),
|
|
128
|
+
(TaskOutputRatingType.five_star, 3, 0.5),
|
|
129
|
+
(TaskOutputRatingType.five_star, 4, 0.75),
|
|
130
|
+
(TaskOutputRatingType.five_star, 5, 1),
|
|
131
|
+
(TaskOutputRatingType.pass_fail, 0, 0),
|
|
132
|
+
(TaskOutputRatingType.pass_fail, 1, 1),
|
|
133
|
+
(TaskOutputRatingType.pass_fail, 0.5, 0.5),
|
|
134
|
+
(TaskOutputRatingType.pass_fail_critical, -1, 0),
|
|
135
|
+
(TaskOutputRatingType.pass_fail_critical, 0, 0.5),
|
|
136
|
+
(TaskOutputRatingType.pass_fail_critical, 1, 1),
|
|
137
|
+
(TaskOutputRatingType.pass_fail_critical, 0.5, 0.75),
|
|
138
|
+
],
|
|
139
|
+
)
|
|
140
|
+
def test_normalize_rating(rating_type, rating, expected):
|
|
141
|
+
assert normalize_rating(rating, rating_type) == expected
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@pytest.mark.parametrize(
|
|
145
|
+
"rating_type,rating",
|
|
146
|
+
[
|
|
147
|
+
(TaskOutputRatingType.five_star, 0),
|
|
148
|
+
(TaskOutputRatingType.five_star, 6),
|
|
149
|
+
(TaskOutputRatingType.pass_fail, -0.5),
|
|
150
|
+
(TaskOutputRatingType.pass_fail, 1.5),
|
|
151
|
+
(TaskOutputRatingType.pass_fail_critical, -1.5),
|
|
152
|
+
(TaskOutputRatingType.pass_fail_critical, 1.5),
|
|
153
|
+
(TaskOutputRatingType.custom, 0),
|
|
154
|
+
(TaskOutputRatingType.custom, 99),
|
|
155
|
+
],
|
|
156
|
+
)
|
|
157
|
+
def test_normalize_rating_errors(rating_type, rating):
|
|
158
|
+
with pytest.raises(ValueError):
|
|
159
|
+
normalize_rating(rating, rating_type)
|
kiln_ai/utils/config.py
CHANGED
|
@@ -142,10 +142,15 @@ class Config:
|
|
|
142
142
|
raise AttributeError(f"Config has no attribute '{name}'")
|
|
143
143
|
|
|
144
144
|
@classmethod
|
|
145
|
-
def
|
|
145
|
+
def settings_dir(cls, create=True):
|
|
146
146
|
settings_dir = os.path.join(Path.home(), ".kiln_ai")
|
|
147
147
|
if create and not os.path.exists(settings_dir):
|
|
148
148
|
os.makedirs(settings_dir)
|
|
149
|
+
return settings_dir
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def settings_path(cls, create=True):
|
|
153
|
+
settings_dir = cls.settings_dir(create)
|
|
149
154
|
return os.path.join(settings_dir, "settings.yaml")
|
|
150
155
|
|
|
151
156
|
@classmethod
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kiln-ai
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: Kiln AI
|
|
5
5
|
Project-URL: Homepage, https://getkiln.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/Kiln-AI/kiln
|
|
@@ -19,8 +19,7 @@ Requires-Dist: jsonschema>=4.23.0
|
|
|
19
19
|
Requires-Dist: langchain-aws>=0.2.4
|
|
20
20
|
Requires-Dist: langchain-fireworks>=0.2.5
|
|
21
21
|
Requires-Dist: langchain-groq>=0.2.0
|
|
22
|
-
Requires-Dist: langchain-ollama>=0.2.
|
|
23
|
-
Requires-Dist: langchain-openai>=0.2.4
|
|
22
|
+
Requires-Dist: langchain-ollama>=0.2.2
|
|
24
23
|
Requires-Dist: langchain>=0.3.5
|
|
25
24
|
Requires-Dist: openai>=1.53.0
|
|
26
25
|
Requires-Dist: pdoc>=15.0.0
|
|
@@ -72,7 +71,8 @@ The library has a [comprehensive set of docs](https://kiln-ai.github.io/Kiln/kil
|
|
|
72
71
|
- [Load an Existing Dataset into a Kiln Task Dataset](#load-an-existing-dataset-into-a-kiln-task-dataset)
|
|
73
72
|
- [Using your Kiln Dataset in a Notebook or Project](#using-your-kiln-dataset-in-a-notebook-or-project)
|
|
74
73
|
- [Using Kiln Dataset in Pandas](#using-kiln-dataset-in-pandas)
|
|
75
|
-
- [
|
|
74
|
+
- [Building and Running a Kiln Task from Code](#building-and-running-a-kiln-task-from-code)
|
|
75
|
+
- [Full API Reference](#full-api-reference)
|
|
76
76
|
|
|
77
77
|
## Installation
|
|
78
78
|
|
|
@@ -95,11 +95,14 @@ The Kiln Python library provides a set of Python classes that which help you eas
|
|
|
95
95
|
|
|
96
96
|
### Datamodel Overview
|
|
97
97
|
|
|
98
|
+
Here's a high level overview of the Kiln datamodel. A project folder will reflect this nested structure:
|
|
99
|
+
|
|
98
100
|
- Project: a Kiln Project that organizes related tasks
|
|
99
101
|
- Task: a specific task including prompt instructions, input/output schemas, and requirements
|
|
100
102
|
- TaskRun: a sample (run) of a task including input, output and human rating information
|
|
101
|
-
- DatasetSplit: a frozen collection of task runs divided into train/test/validation splits
|
|
102
103
|
- Finetune: configuration and status tracking for fine-tuning models on task data
|
|
104
|
+
- Prompt: a prompt for this task
|
|
105
|
+
- DatasetSplit: a frozen collection of task runs divided into train/test/validation splits
|
|
103
106
|
|
|
104
107
|
### Load a Project
|
|
105
108
|
|
|
@@ -230,8 +233,43 @@ final_df = pd.concat(dfs, ignore_index=True)
|
|
|
230
233
|
print(final_df)
|
|
231
234
|
```
|
|
232
235
|
|
|
233
|
-
###
|
|
236
|
+
### Building and Running a Kiln Task from Code
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
# Step 1: Create or Load a Task -- choose one of the following 1.A or 1.B
|
|
240
|
+
|
|
241
|
+
# Step 1.A: Optionally load an existing task from disk
|
|
242
|
+
# task = datamodel.Task.load_from_file("path/to/task.kiln")
|
|
243
|
+
|
|
244
|
+
# Step 1.B: Create a new task in code, without saving to disk.
|
|
245
|
+
task = datamodel.Task(
|
|
246
|
+
name="test task",
|
|
247
|
+
instruction="Tell a joke, given a subject.",
|
|
248
|
+
)
|
|
249
|
+
# replace with a valid JSON schema https://json-schema.org for your task (json string, not a python dict).
|
|
250
|
+
# Or delete this line to use plaintext output
|
|
251
|
+
task.output_json_schema = json_joke_schema
|
|
252
|
+
|
|
253
|
+
# Step 2: Create an Adapter to run the task, with a specific model and provider
|
|
254
|
+
adapter = adapter_for_task(task, model_name="llama_3_1_8b", provider="groq")
|
|
255
|
+
|
|
256
|
+
# Step 3: Invoke the Adapter to run the task
|
|
257
|
+
task_input = "cows"
|
|
258
|
+
response = await adapter.invoke(task_input)
|
|
259
|
+
print(f"Output: {response.output.output}")
|
|
260
|
+
|
|
261
|
+
# Step 4 (optional): Load the task from disk and print the results.
|
|
262
|
+
# This will only work if the task was loaded from disk, or you called task.save_to_file() before invoking the adapter (epemerial tasks don't save their result to disk)
|
|
263
|
+
task = datamodel.Task.load_from_file(tmp_path / "test_task.kiln")
|
|
264
|
+
for run in task.runs():
|
|
265
|
+
print(f"Run: {run.id}")
|
|
266
|
+
print(f"Input: {run.input}")
|
|
267
|
+
print(f"Output: {run.output}")
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Full API Reference
|
|
234
272
|
|
|
235
273
|
The library can do a lot more than the examples we've shown here.
|
|
236
274
|
|
|
237
|
-
See the [docs](https://kiln-ai.github.io/Kiln/kiln_core_docs/index.html)
|
|
275
|
+
See the full API reference in the [docs](https://kiln-ai.github.io/Kiln/kiln_core_docs/index.html) under the `Submodules` section of the sidebar.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
kiln_ai/__init__.py,sha256=Sc4z8LRVFMwJUoc_DPVUriSXTZ6PO9MaJ80PhRbKyB8,34
|
|
2
|
+
kiln_ai/adapters/__init__.py,sha256=4qEnFkkRSHPKDU7AvYNkqXECjZO_K7PzDCK3HbsY7o4,902
|
|
3
|
+
kiln_ai/adapters/adapter_registry.py,sha256=o7JhzL627W3WMvpztsI_D0pqLPXP-IgIf3e-o7DAVxE,3720
|
|
4
|
+
kiln_ai/adapters/ml_model_list.py,sha256=IzxswO2zORd7bsovswvRpZMwIs1BZcMtPcnhLZ7xzkk,40969
|
|
5
|
+
kiln_ai/adapters/ollama_tools.py,sha256=ZkiGCaocKTMsb1JoySupv9a1OQuE72CCuKsNpyp6jNU,3551
|
|
6
|
+
kiln_ai/adapters/prompt_builders.py,sha256=LYHTIaisQMBFtWDRIGo1QJgOsmQ-NBpQ8fI4eImHxaQ,15269
|
|
7
|
+
kiln_ai/adapters/provider_tools.py,sha256=CGNLW0xhFyj93HFwznCoDrrbyQbQAaS2mJuOKaMB6gU,14435
|
|
8
|
+
kiln_ai/adapters/run_output.py,sha256=_WVNqJ9cQehgEJR3Jy5_Pp29QnurpmEf-S6UU6WAegE,271
|
|
9
|
+
kiln_ai/adapters/test_adapter_registry.py,sha256=opowxLBWm0lZTPL9S4qEaOS8HB82dTpZeNuhpE_cNHU,6379
|
|
10
|
+
kiln_ai/adapters/test_generate_docs.py,sha256=RQ5flkg4fbosj_fB3RiRZyXSqD_UtOHNBYJsne6UkzU,2782
|
|
11
|
+
kiln_ai/adapters/test_ollama_tools.py,sha256=xAUzL0IVmmXadVehJu1WjqbhpKEYGAgGt3pWx7hrubc,2514
|
|
12
|
+
kiln_ai/adapters/test_prompt_adaptors.py,sha256=CKyToDKS4v-tQO9pq4tiq_ypnY4ePhY9yrRAtG-58p0,7516
|
|
13
|
+
kiln_ai/adapters/test_prompt_builders.py,sha256=5Xvfr-oQg_LLrle6UqfpRHWcPUYa8ywG3aL1rM7q1Jw,22054
|
|
14
|
+
kiln_ai/adapters/test_provider_tools.py,sha256=DtnC6oFuiBvvbhD-kdCcWzEYqXZfMBM_DexuQdyAVR8,28664
|
|
15
|
+
kiln_ai/adapters/data_gen/__init__.py,sha256=QTZWaf7kq5BorhPvexJfwDEKmjRmIbhwW9ei8LW2SIs,276
|
|
16
|
+
kiln_ai/adapters/data_gen/data_gen_prompts.py,sha256=kudjHnAz7L3q0k_NLyTlaIV7M0uRFrxXNcfcnjOE2uc,5810
|
|
17
|
+
kiln_ai/adapters/data_gen/data_gen_task.py,sha256=0PuYCcj09BtpgNj23mKj_L45mKZBdV5VreUeZ-Tj_xM,6642
|
|
18
|
+
kiln_ai/adapters/data_gen/test_data_gen_task.py,sha256=cRKUKMvC0uVompbmPTKwbnQ_N3c0cQDm4J_9H4Y5U18,10129
|
|
19
|
+
kiln_ai/adapters/eval/base_eval.py,sha256=jVXMiVBC07ZnLEuZVAjUAYewsnuV99put39n_GZcG1M,7261
|
|
20
|
+
kiln_ai/adapters/eval/eval_runner.py,sha256=A8GhVEt4J_p2-EZlN592blVxY0anKiMiLgac155pcfQ,10688
|
|
21
|
+
kiln_ai/adapters/eval/g_eval.py,sha256=VXYZi-5WG8Go4E2shaOL4D3V2cL_c2zmEno2N1b2WPM,14295
|
|
22
|
+
kiln_ai/adapters/eval/registry.py,sha256=gZ_s0VgEx79Fswkgi1tS4yOl7lzpkvUBJZ62RldhM_w,626
|
|
23
|
+
kiln_ai/adapters/eval/test_base_eval.py,sha256=AGq09bziZm9zh_37PP59AzpkWW7hQU1o7vHSiDsObhY,10723
|
|
24
|
+
kiln_ai/adapters/eval/test_eval_runner.py,sha256=58jRE_2qHZmsDlMj41DrbgE8w9PKC9wwAT-vbi_R4Ec,18567
|
|
25
|
+
kiln_ai/adapters/eval/test_g_eval.py,sha256=wcR56b3vSKn88JeCCQz92p8TMgZlgSP1ged_XlFrYlg,16162
|
|
26
|
+
kiln_ai/adapters/eval/test_g_eval_data.py,sha256=8caiZfLWnXVX8alrBPrH7L7gqqSS9vO7u6PzcHurQcA,27769
|
|
27
|
+
kiln_ai/adapters/fine_tune/__init__.py,sha256=DxdTR60chwgck1aEoVYWyfWi6Ed2ZkdJj0lar-SEAj4,257
|
|
28
|
+
kiln_ai/adapters/fine_tune/base_finetune.py,sha256=n3mfE_3bhhzmN_MQxO5qNezN-qpl4WFamZ3ih41dx4o,6069
|
|
29
|
+
kiln_ai/adapters/fine_tune/dataset_formatter.py,sha256=qRhSSkMhTWn13OMb6LKPVwAU7uY4bB49GDiVSuhDkNg,14449
|
|
30
|
+
kiln_ai/adapters/fine_tune/finetune_registry.py,sha256=H1B-opCTlIyd9JlIFTKsY_ctxUX9ziEc49_gnmg1SZg,483
|
|
31
|
+
kiln_ai/adapters/fine_tune/fireworks_finetune.py,sha256=6IfTDn_8tg6PR0OFudRx6V7Wjvf4P7t0fm_xyRwII68,13978
|
|
32
|
+
kiln_ai/adapters/fine_tune/openai_finetune.py,sha256=Dz9E_0BWfrIkvv8ArZe-RKPwbIKPZ3v8rfbc3JELyTY,8571
|
|
33
|
+
kiln_ai/adapters/fine_tune/test_base_finetune.py,sha256=0zWxFYrDGVuoQNQmi9vVUEkBc4mstfHnsUjQmiJA-sE,10864
|
|
34
|
+
kiln_ai/adapters/fine_tune/test_dataset_formatter.py,sha256=T3jbFZooLVBaGCE0LUVxwPxzM3l8IY41zUj3jPk-Zi8,24027
|
|
35
|
+
kiln_ai/adapters/fine_tune/test_fireworks_tinetune.py,sha256=e88z5-KtU9Y7frXqCVy6r6iE6S-tInn5oMOqmSnbR2I,18144
|
|
36
|
+
kiln_ai/adapters/fine_tune/test_openai_finetune.py,sha256=H63Xk2PNHbt5Ev5IQpdR9JZ4uz-Huo2gfuC4mHHqe0w,20011
|
|
37
|
+
kiln_ai/adapters/model_adapters/__init__.py,sha256=FyNq-twr1zQR55Hd_sDlTcVZ8JsZ9jrIBBURtZNjlss,272
|
|
38
|
+
kiln_ai/adapters/model_adapters/base_adapter.py,sha256=tY67FJlWzYY-Ha1FyBMes3KacklFfTSqvU6-crILQsc,9597
|
|
39
|
+
kiln_ai/adapters/model_adapters/langchain_adapters.py,sha256=LVggQGeg_fIol1uYo375JHmjh7pwDhCACVe1K7lh28Y,12996
|
|
40
|
+
kiln_ai/adapters/model_adapters/openai_compatible_config.py,sha256=oxiUUESM9f5EVMePDSJI7s6YaMmmBkFMCEdxA50mwgw,241
|
|
41
|
+
kiln_ai/adapters/model_adapters/openai_model_adapter.py,sha256=KuCPFuNZ5aZwymLL8k87PNjUVOs9JyR91W7VKtw9yN8,11438
|
|
42
|
+
kiln_ai/adapters/model_adapters/test_base_adapter.py,sha256=uQyKrHLN3Jha6R-6SWkEME6brQecVFdPTSXogo-xpt0,6556
|
|
43
|
+
kiln_ai/adapters/model_adapters/test_langchain_adapter.py,sha256=PArWTKytzUoM9Lc9Q0bEOcvZDNTF2SzfR9ln8sf0Hzg,11884
|
|
44
|
+
kiln_ai/adapters/model_adapters/test_openai_model_adapter.py,sha256=CV6a3Sf3f3szpk1MLBoAjcuL5B5-4n86j8tMlEA-Bhg,6844
|
|
45
|
+
kiln_ai/adapters/model_adapters/test_saving_adapter_results.py,sha256=1XFQQxdSIbqSoQEdxHOYJcY0cMb59qpTDPOmL9bW4B8,7870
|
|
46
|
+
kiln_ai/adapters/model_adapters/test_structured_output.py,sha256=7N5xniBWXDxwb4gvV8k0bbrlTir2kWBE6Q_z2azBJvs,11865
|
|
47
|
+
kiln_ai/adapters/parsers/__init__.py,sha256=TGJS_8JhjUwg5Bnq4cDmwt5eIRo4vowmcL2A72L1Hzk,202
|
|
48
|
+
kiln_ai/adapters/parsers/base_parser.py,sha256=DaoZVEOOuFTMZd5ZTpl_as6-xc9NPWGP2fAmP12J58M,389
|
|
49
|
+
kiln_ai/adapters/parsers/json_parser.py,sha256=IszrBrhIFrrVr76UZsuejkBdqpZG27mU72264HVgVzE,1274
|
|
50
|
+
kiln_ai/adapters/parsers/parser_registry.py,sha256=G9bAZrnWrR0a82JAQHsSqA2o7-CjrZUBANZljY_6ZxE,623
|
|
51
|
+
kiln_ai/adapters/parsers/r1_parser.py,sha256=9nMEWDAbRSTFuu_--0HMVfVg9IYSoUNQHHw9OxETlRw,2558
|
|
52
|
+
kiln_ai/adapters/parsers/test_json_parser.py,sha256=9kdWe_vRC5wjP8A1Ym6Zu6enDIz4ARCNiRpcZr7_3ak,1971
|
|
53
|
+
kiln_ai/adapters/parsers/test_parser_registry.py,sha256=S4MdX7cnhCbmeKq8tZwMwRdGWr-019Z-fw5zey9Wm08,1043
|
|
54
|
+
kiln_ai/adapters/parsers/test_r1_parser.py,sha256=Ys1ICRNVgt54rf8IEKNav5sz9zHYvvcVAUuoSwwftg8,4517
|
|
55
|
+
kiln_ai/adapters/repair/__init__.py,sha256=dOO9MEpEhjiwzDVFg3MNfA2bKMPlax9iekDatpTkX8E,217
|
|
56
|
+
kiln_ai/adapters/repair/repair_task.py,sha256=iW0bHWQq6Tir6ULTATWFS0zpwNji8Tbwhm2lZu52RsM,3342
|
|
57
|
+
kiln_ai/adapters/repair/test_repair_task.py,sha256=iY7h-o-hnB0zwlkX--WuQlCsd5sKbhksS0hIIPCxt7E,7944
|
|
58
|
+
kiln_ai/datamodel/__init__.py,sha256=GbRfDrdSq9d_-HxzmFIicTmLO3qz-O3XGvSwDPh3XCk,1957
|
|
59
|
+
kiln_ai/datamodel/basemodel.py,sha256=TwMBfNFJ7-5bp2QOoTQUl_YVrF0pkDAk5Rdk6EWEXxI,22143
|
|
60
|
+
kiln_ai/datamodel/datamodel_enums.py,sha256=w8aJeuLWdrH6ZCZ0y2-o0IOmXcl7qXpOMHyrHHoJmkA,2040
|
|
61
|
+
kiln_ai/datamodel/dataset_filters.py,sha256=hWKxGJ-mSl4y0igyNcpmRoRYCiGrf0_uN4MMU9Fe_ng,3180
|
|
62
|
+
kiln_ai/datamodel/dataset_split.py,sha256=q4l4SlUvjLV547bzk7Z-fbmj_o26GDcYOZ2rA5RPh3c,5612
|
|
63
|
+
kiln_ai/datamodel/eval.py,sha256=kio2LqQ87MsP75DJTiIVdVfopTZXH4xjGN9g11V1mUU,13826
|
|
64
|
+
kiln_ai/datamodel/finetune.py,sha256=TYoNVRAfbjqvrY-1YmHwG6xSoDljiJWuuVcTbvQAJL4,4569
|
|
65
|
+
kiln_ai/datamodel/json_schema.py,sha256=sjc2LkbWWFhlqX5QOvLeWrovkmoX_tn3iQquxKDA8Pk,2990
|
|
66
|
+
kiln_ai/datamodel/model_cache.py,sha256=9X4aAigbkFdytckgw8InCMh86uBna0ME_1HJSeMPEn0,4495
|
|
67
|
+
kiln_ai/datamodel/project.py,sha256=uVH2_3TDFtsG_tpts81A-zbd9uPDFxAwMCKZt_km3IE,727
|
|
68
|
+
kiln_ai/datamodel/prompt.py,sha256=70JPYHfgyX18cHW_DXoMzIOA28Jbaz6gyabElmpycyc,1161
|
|
69
|
+
kiln_ai/datamodel/prompt_id.py,sha256=eU2TV0RZapn-BgnZ4sOSNOOVEQ3aPaLzW4YSYCd3OBo,2531
|
|
70
|
+
kiln_ai/datamodel/registry.py,sha256=XwGFXJFKZtOpR1Z9ven6SftggfADdZRm8TFxCEVtfUQ,957
|
|
71
|
+
kiln_ai/datamodel/strict_mode.py,sha256=sm4Xka8mnJHCShtbh6MMU5dDQv-cLj8lHgHkmFKpsl0,849
|
|
72
|
+
kiln_ai/datamodel/task.py,sha256=r-_zgrQCIiIkN8gvBISdU449Z9oKp7E1XL0lkik_rVI,7036
|
|
73
|
+
kiln_ai/datamodel/task_output.py,sha256=0h4QvzV-hksE_AGHWsUHbYf5F95Zn7uU7WFbeIbAEck,12507
|
|
74
|
+
kiln_ai/datamodel/task_run.py,sha256=yquE0jyr_9WzcvrMsEmZfXUnn8zZDEZIXZhVcVBMrT8,7038
|
|
75
|
+
kiln_ai/datamodel/test_basemodel.py,sha256=KJLJf0stuQq4ksOtoPM_w1VQrGz2FGdOT6cdrMkib9s,17750
|
|
76
|
+
kiln_ai/datamodel/test_dataset_filters.py,sha256=v88QPkIsq4diUmoUF3-qj5KAW2rLRp0KDAm_pexbFy4,1894
|
|
77
|
+
kiln_ai/datamodel/test_dataset_split.py,sha256=5CHO1Lq4xQBB72tV2SPER7OZODJNvj15qxi_cYBV2Rs,11157
|
|
78
|
+
kiln_ai/datamodel/test_datasource.py,sha256=Pzh1l20__xObgdBaIMNJarG-jwmEsujRFkRmUBLuK0g,3220
|
|
79
|
+
kiln_ai/datamodel/test_eval_model.py,sha256=J7MqwWBgPpeXGqh3IacVUUHdZFJSZ2MgTsUNu-hNOJw,19528
|
|
80
|
+
kiln_ai/datamodel/test_example_models.py,sha256=fpqh0u7zFhWHcRHgtxCjX8RD2oKHYOP_mJJymaUhEZU,20944
|
|
81
|
+
kiln_ai/datamodel/test_json_schema.py,sha256=UgKwAFcdrJTq2byh7Yf-HoSAtiHiGAsNZxfkIvoMxIg,3915
|
|
82
|
+
kiln_ai/datamodel/test_model_cache.py,sha256=Fy-ucYNzS5JEG-8SFY4nVHA8iRbXXxai20f8_oGl97o,8184
|
|
83
|
+
kiln_ai/datamodel/test_model_perf.py,sha256=NdD7L8XraGkunaEKGPsfYwdcbIgdjhFanOO3G6hU158,3235
|
|
84
|
+
kiln_ai/datamodel/test_models.py,sha256=hmV7sTbOamWJCwOY96w-g4PQRv4Uai-XaHtg0QKH-ak,19295
|
|
85
|
+
kiln_ai/datamodel/test_nested_save.py,sha256=xciCddqvPyKyoyjC5Lx_3Kh1t4LJv1xYRAPazR3SRcs,5588
|
|
86
|
+
kiln_ai/datamodel/test_output_rating.py,sha256=zvPIp2shAgCs2RQBgwYoL09fRA3krHvgAqUa91RlWR0,15125
|
|
87
|
+
kiln_ai/datamodel/test_prompt_id.py,sha256=ihyXVPQi0dSLGnBM7rTXRnVaiWXhh7HJmSy4nZZKmso,4225
|
|
88
|
+
kiln_ai/datamodel/test_registry.py,sha256=PhS4anLi5Bf_023obuTlO5DALhtPB8WIc_bX12Yg6Po,2705
|
|
89
|
+
kiln_ai/datamodel/test_task.py,sha256=FYyoEqJXQIy8rcBsLTdki4-1z9COnZQk1-aoS3ZoNuU,5307
|
|
90
|
+
kiln_ai/utils/__init__.py,sha256=PTD0MwBCKAMIOGsTAwsFaJOusTJJoRFTfOGqRvCaU-E,142
|
|
91
|
+
kiln_ai/utils/config.py,sha256=9navMS2ooSviz74Bq8raf5-01DFfDf9SSVfpasIIPlo,6993
|
|
92
|
+
kiln_ai/utils/exhaustive_error.py,sha256=TkkRixIAR3CPEKHeAJzyv0mtxp6BxUBKMvobA3vzQug,262
|
|
93
|
+
kiln_ai/utils/formatting.py,sha256=VtB9oag0lOGv17dwT7OPX_3HzBfaU9GsLH-iLete0yM,97
|
|
94
|
+
kiln_ai/utils/name_generator.py,sha256=v26TgpCwQbhQFcZvzgjZvURinjrOyyFhxpsI6NQrHKc,1914
|
|
95
|
+
kiln_ai/utils/test_config.py,sha256=Jw3nMFeIgZUsZDRJJY2HpB-2EkR2NoZ-rDe_o9oA7ws,9174
|
|
96
|
+
kiln_ai/utils/test_name_geneator.py,sha256=9-hSTBshyakqlPbFnNcggwLrL7lcPTitauBYHg9jFWI,1513
|
|
97
|
+
kiln_ai-0.12.0.dist-info/METADATA,sha256=CnOHwkyknO0XqFIRL65XVEQl_375cHnvMneIy8J3PWE,10656
|
|
98
|
+
kiln_ai-0.12.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
99
|
+
kiln_ai-0.12.0.dist-info/licenses/LICENSE.txt,sha256=_NA5pnTYgRRr4qH6lE3X-TuZJ8iRcMUi5ASoGr-lEx8,1209
|
|
100
|
+
kiln_ai-0.12.0.dist-info/RECORD,,
|
kiln_ai/adapters/base_adapter.py
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from abc import ABCMeta, abstractmethod
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from typing import Dict
|
|
5
|
-
|
|
6
|
-
from kiln_ai.datamodel import (
|
|
7
|
-
DataSource,
|
|
8
|
-
DataSourceType,
|
|
9
|
-
Task,
|
|
10
|
-
TaskOutput,
|
|
11
|
-
TaskRun,
|
|
12
|
-
)
|
|
13
|
-
from kiln_ai.datamodel.json_schema import validate_schema
|
|
14
|
-
from kiln_ai.utils.config import Config
|
|
15
|
-
|
|
16
|
-
from .prompt_builders import BasePromptBuilder, SimplePromptBuilder
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclass
|
|
20
|
-
class AdapterInfo:
|
|
21
|
-
adapter_name: str
|
|
22
|
-
model_name: str
|
|
23
|
-
model_provider: str
|
|
24
|
-
prompt_builder_name: str
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclass
|
|
28
|
-
class RunOutput:
|
|
29
|
-
output: Dict | str
|
|
30
|
-
intermediate_outputs: Dict[str, str] | None
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class BaseAdapter(metaclass=ABCMeta):
|
|
34
|
-
"""Base class for AI model adapters that handle task execution.
|
|
35
|
-
|
|
36
|
-
This abstract class provides the foundation for implementing model-specific adapters
|
|
37
|
-
that can process tasks with structured or unstructured inputs/outputs. It handles
|
|
38
|
-
input/output validation, prompt building, and run tracking.
|
|
39
|
-
|
|
40
|
-
Attributes:
|
|
41
|
-
prompt_builder (BasePromptBuilder): Builder for constructing prompts for the model
|
|
42
|
-
kiln_task (Task): The task configuration and metadata
|
|
43
|
-
output_schema (dict | None): JSON schema for validating structured outputs
|
|
44
|
-
input_schema (dict | None): JSON schema for validating structured inputs
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
def __init__(
|
|
48
|
-
self,
|
|
49
|
-
kiln_task: Task,
|
|
50
|
-
prompt_builder: BasePromptBuilder | None = None,
|
|
51
|
-
tags: list[str] | None = None,
|
|
52
|
-
):
|
|
53
|
-
self.prompt_builder = prompt_builder or SimplePromptBuilder(kiln_task)
|
|
54
|
-
self.kiln_task = kiln_task
|
|
55
|
-
self.output_schema = self.kiln_task.output_json_schema
|
|
56
|
-
self.input_schema = self.kiln_task.input_json_schema
|
|
57
|
-
self.default_tags = tags
|
|
58
|
-
|
|
59
|
-
async def invoke_returning_raw(
|
|
60
|
-
self,
|
|
61
|
-
input: Dict | str,
|
|
62
|
-
input_source: DataSource | None = None,
|
|
63
|
-
) -> Dict | str:
|
|
64
|
-
result = await self.invoke(input, input_source)
|
|
65
|
-
if self.kiln_task.output_json_schema is None:
|
|
66
|
-
return result.output.output
|
|
67
|
-
else:
|
|
68
|
-
return json.loads(result.output.output)
|
|
69
|
-
|
|
70
|
-
async def invoke(
|
|
71
|
-
self,
|
|
72
|
-
input: Dict | str,
|
|
73
|
-
input_source: DataSource | None = None,
|
|
74
|
-
) -> TaskRun:
|
|
75
|
-
# validate input
|
|
76
|
-
if self.input_schema is not None:
|
|
77
|
-
if not isinstance(input, dict):
|
|
78
|
-
raise ValueError(f"structured input is not a dict: {input}")
|
|
79
|
-
validate_schema(input, self.input_schema)
|
|
80
|
-
|
|
81
|
-
# Run
|
|
82
|
-
run_output = await self._run(input)
|
|
83
|
-
|
|
84
|
-
# validate output
|
|
85
|
-
if self.output_schema is not None:
|
|
86
|
-
if not isinstance(run_output.output, dict):
|
|
87
|
-
raise RuntimeError(
|
|
88
|
-
f"structured response is not a dict: {run_output.output}"
|
|
89
|
-
)
|
|
90
|
-
validate_schema(run_output.output, self.output_schema)
|
|
91
|
-
else:
|
|
92
|
-
if not isinstance(run_output.output, str):
|
|
93
|
-
raise RuntimeError(
|
|
94
|
-
f"response is not a string for non-structured task: {run_output.output}"
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
# Generate the run and output
|
|
98
|
-
run = self.generate_run(input, input_source, run_output)
|
|
99
|
-
|
|
100
|
-
# Save the run if configured to do so, and we have a path to save to
|
|
101
|
-
if Config.shared().autosave_runs and self.kiln_task.path is not None:
|
|
102
|
-
run.save_to_file()
|
|
103
|
-
else:
|
|
104
|
-
# Clear the ID to indicate it's not persisted
|
|
105
|
-
run.id = None
|
|
106
|
-
|
|
107
|
-
return run
|
|
108
|
-
|
|
109
|
-
def has_structured_output(self) -> bool:
|
|
110
|
-
return self.output_schema is not None
|
|
111
|
-
|
|
112
|
-
@abstractmethod
|
|
113
|
-
def adapter_info(self) -> AdapterInfo:
|
|
114
|
-
pass
|
|
115
|
-
|
|
116
|
-
@abstractmethod
|
|
117
|
-
async def _run(self, input: Dict | str) -> RunOutput:
|
|
118
|
-
pass
|
|
119
|
-
|
|
120
|
-
def build_prompt(self) -> str:
|
|
121
|
-
return self.prompt_builder.build_prompt()
|
|
122
|
-
|
|
123
|
-
# create a run and task output
|
|
124
|
-
def generate_run(
|
|
125
|
-
self, input: Dict | str, input_source: DataSource | None, run_output: RunOutput
|
|
126
|
-
) -> TaskRun:
|
|
127
|
-
# Convert input and output to JSON strings if they are dictionaries
|
|
128
|
-
input_str = json.dumps(input) if isinstance(input, dict) else input
|
|
129
|
-
output_str = (
|
|
130
|
-
json.dumps(run_output.output)
|
|
131
|
-
if isinstance(run_output.output, dict)
|
|
132
|
-
else run_output.output
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
# If no input source is provided, use the human data source
|
|
136
|
-
if input_source is None:
|
|
137
|
-
input_source = DataSource(
|
|
138
|
-
type=DataSourceType.human,
|
|
139
|
-
properties={"created_by": Config.shared().user_id},
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
new_task_run = TaskRun(
|
|
143
|
-
parent=self.kiln_task,
|
|
144
|
-
input=input_str,
|
|
145
|
-
input_source=input_source,
|
|
146
|
-
output=TaskOutput(
|
|
147
|
-
output=output_str,
|
|
148
|
-
# Synthetic since an adapter, not a human, is creating this
|
|
149
|
-
source=DataSource(
|
|
150
|
-
type=DataSourceType.synthetic,
|
|
151
|
-
properties=self._properties_for_task_output(),
|
|
152
|
-
),
|
|
153
|
-
),
|
|
154
|
-
intermediate_outputs=run_output.intermediate_outputs,
|
|
155
|
-
tags=self.default_tags or [],
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
exclude_fields = {
|
|
159
|
-
"id": True,
|
|
160
|
-
"created_at": True,
|
|
161
|
-
"updated_at": True,
|
|
162
|
-
"path": True,
|
|
163
|
-
"output": {"id": True, "created_at": True, "updated_at": True},
|
|
164
|
-
}
|
|
165
|
-
new_run_dump = new_task_run.model_dump(exclude=exclude_fields)
|
|
166
|
-
|
|
167
|
-
# Check if the same run already exists
|
|
168
|
-
existing_task_run = next(
|
|
169
|
-
(
|
|
170
|
-
task_run
|
|
171
|
-
for task_run in self.kiln_task.runs()
|
|
172
|
-
if task_run.model_dump(exclude=exclude_fields) == new_run_dump
|
|
173
|
-
),
|
|
174
|
-
None,
|
|
175
|
-
)
|
|
176
|
-
if existing_task_run:
|
|
177
|
-
return existing_task_run
|
|
178
|
-
|
|
179
|
-
return new_task_run
|
|
180
|
-
|
|
181
|
-
def _properties_for_task_output(self) -> Dict[str, str | int | float]:
|
|
182
|
-
props = {}
|
|
183
|
-
|
|
184
|
-
# adapter info
|
|
185
|
-
adapter_info = self.adapter_info()
|
|
186
|
-
props["adapter_name"] = adapter_info.adapter_name
|
|
187
|
-
props["model_name"] = adapter_info.model_name
|
|
188
|
-
props["model_provider"] = adapter_info.model_provider
|
|
189
|
-
props["prompt_builder_name"] = adapter_info.prompt_builder_name
|
|
190
|
-
|
|
191
|
-
return props
|