You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Improved validations
* Fix type hint
* Change run_local to run, function to callable and allow for runtime on HL evals
* Fix error messages
* More logging tweaks
---------
Co-authored-by: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
"""A File on Humanloop (Flow, Prompt, Tool, Evaluator)."""
86
86
type: NotRequired[FileType]
87
87
"""The type of File this function relates to on Humanloop."""
88
88
version: NotRequired[Version]
89
-
"""The contents uniquely define the version of the File on Humanloop"""
90
-
function: Callable
89
+
"""The contents uniquely define the version of the File on Humanloop."""
90
+
callable: Callable
91
91
"""The function being evaluated.
92
-
It will be called using your Dataset `inputs` as follows: `output = function(**datapoint.inputs)`.
93
-
If `messages` are defined in your Dataset, then `output = function(**datapoint.inputs, messages=datapoint.messages)`.
92
+
It will be called using your Dataset `inputs` as follows: `output = callable(**datapoint.inputs)`.
93
+
If `messages` are defined in your Dataset, then `output = callable(**datapoint.inputs, messages=datapoint.messages)`.
94
94
It should return a single string output. If not, you must provide a `custom_logger`.
95
95
"""
96
96
custom_logger: NotRequired[Callable]
97
97
"""function that logs the output of your function to Humanloop, replacing the default logging.
98
98
If provided, it will be called as follows:
99
99
```
100
-
output = function(**datapoint.inputs).
100
+
output = callable(**datapoint.inputs).
101
101
log = custom_logger(client, output)
102
102
```
103
103
Inside the custom_logger, you can use the Humanloop `client` to log the output of your function.
@@ -119,12 +119,12 @@ class Evaluator(Identifiers):
119
119
"""The type of arguments the Evaluator expects - only required for local Evaluators."""
120
120
return_type: NotRequired[EvaluatorReturnTypeEnum]
121
121
"""The type of return value the Evaluator produces - only required for local Evaluators."""
122
-
function: NotRequired[Callable]
122
+
callable: NotRequired[Callable]
123
123
"""The function to run on the logs to produce the judgment - only required for local Evaluators."""
124
124
custom_logger: NotRequired[Callable]
125
125
"""optional function that logs the output judgment from your Evaluator to Humanloop, if provided, it will be called as follows:
126
126
```
127
-
judgment = function(log_dict)
127
+
judgment = callable(log_dict)
128
128
log = custom_logger(client, judgmemt)
129
129
```
130
130
Inside the custom_logger, you can use the Humanloop `client` to log the judgment to Humanloop.
@@ -157,7 +157,7 @@ def _run_eval(
157
157
dataset: Dataset,
158
158
evaluators: Optional[Sequence[Evaluator]] =None,
159
159
# logs: typing.Sequence[dict] | None = None,
160
-
workers: int=5,
160
+
workers: int=4,
161
161
) ->List[EvaluatorCheck]:
162
162
"""
163
163
Evaluate your function for a given `Dataset` and set of `Evaluators`.
@@ -173,23 +173,30 @@ def _run_eval(
173
173
174
174
# Get or create the file on Humanloop
175
175
version=file.pop("version", {})
176
+
176
177
# Raise error if one of path or id not provided
177
178
ifnotfile.get("path") andnotfile.get("id"):
178
179
raiseValueError("You must provide a path or id in your `file`.")
179
180
180
-
try:
181
-
function_=file.pop("function")
182
-
exceptKeyErroras_:
183
-
raiseValueError("You must provide a `function` for your `file` to run a local eval.")
184
-
181
+
# Determine the `type` of the `file` to Evaluate - if not `type` provided, default to `flow`
185
182
try:
186
183
type_=file.pop("type")
187
-
logger.info(f"{CYAN}Evaluating your {type_} function corresponding to `{file['path']}` on Humanloop{RESET}\n\n")
184
+
logger.info(
185
+
f"{CYAN}Evaluating your {type_} function corresponding to `{file['path']}` on Humanloop{RESET}\n\n")
188
186
exceptKeyErroras_:
189
-
# Default to flows if not type specified
190
187
type_="flow"
191
188
logger.warning("No `file` type specified, defaulting to flow.")
192
189
190
+
# If a `callable` is provided, Logs will be generated locally, otherwise Logs will be generated on Humanloop.
191
+
function_=None
192
+
try:
193
+
function_=file.pop("callable")
194
+
exceptKeyErroras_:
195
+
iftype_=="flow":
196
+
raiseValueError("You must provide a `callable` for your Flow `file` to run a local eval.")
197
+
else:
198
+
logger.info(f"No `callable` provided for your {type_} file - will attempt to generate logs on Humanloop.")
199
+
193
200
custom_logger=file.pop("custom_logger", None)
194
201
file_dict= {**file, **version}
195
202
@@ -234,8 +241,11 @@ def _run_eval(
234
241
ifevaluators:
235
242
forevaluatorinevaluators:
236
243
# If a callable is provided for an Evaluator, we treat it as External
237
-
eval_function=evaluator.get("function")
244
+
eval_function=evaluator.get("callable")
238
245
ifeval_functionisnotNone:
246
+
# TODO: support the case where `file` logs generated on Humanloop but Evaluator logs generated locally
247
+
iffunction_isNone:
248
+
raiseValueError(f"Local Evaluators are only supported when generating Logs locally using your {type_}'s `callable`. Please provide a `callable` for your file in order to run Evaluators locally.")
0 commit comments