Skip to content

Commit 33c24b2

Browse files
author
Andrei Bratu
committed
allow eval run to use files on HL workspace
1 parent fcefc53 commit 33c24b2

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

src/humanloop/evals/run.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
)
3636

3737
from humanloop import EvaluatorResponse, FlowResponse, PromptResponse, ToolResponse
38+
from humanloop.agents.client import AgentsClient
3839
from humanloop.core.api_error import ApiError
3940
from humanloop.context import (
4041
EvaluationContext,
@@ -100,7 +101,7 @@
100101
RESET = "\033[0m"
101102

102103

103-
CLIENT_TYPE = TypeVar("CLIENT_TYPE", PromptsClient, ToolsClient, FlowsClient, EvaluatorsClient)
104+
CLIENT_TYPE = TypeVar("CLIENT_TYPE", PromptsClient, ToolsClient, FlowsClient, EvaluatorsClient, AgentsClient)
104105

105106

106107
def run_eval(
@@ -135,14 +136,35 @@ def run_eval(
135136
% (type_.capitalize(), decorator_type.capitalize())
136137
)
137138

139+
# Check if file exists on Humanloop before trying to upsert
140+
file_exists = False
138141
try:
139-
hl_file = _upsert_file(file=file_, type=type_, client=client)
140-
except ValidationError as e:
141-
sys.stdout.write(f"{RED}Error in your `file` argument:\n\n{e}{RESET}")
142-
return []
143-
except Exception as e:
144-
sys.stdout.write(f"{RED}Error in your `file` argument:\n\n{e}{RESET}")
145-
return []
142+
path_ = file_.get("path")
143+
hl_file = client.files.retrieve_by_path(path=path_)
144+
if hl_file.type != type_:
145+
sys.stdout.write(
146+
f"{RED}Error in your `file` argument:\n\nThe file type {hl_file.type} does not "
147+
f"match the type of the File at {path_}: {type_}.{RESET}"
148+
)
149+
return []
150+
file_exists = True
151+
sys.stdout.write(f"{CYAN}Using the File definition from Humanloop workspace: {path_}{RESET}")
152+
except ApiError as e:
153+
if e.status_code == 404:
154+
# Let's create the file
155+
pass
156+
else:
157+
sys.stdout.write(f"{RED}Error in your `file` argument:\n\n{e}{RESET}")
158+
return []
159+
if not file_exists:
160+
try:
161+
hl_file = _upsert_file(file=file_, type=type_, client=client)
162+
except ValidationError as e:
163+
sys.stdout.write(f"{RED}Error in your `file` argument:\n\n{e}{RESET}")
164+
return []
165+
except Exception as e:
166+
sys.stdout.write(f"{RED}Error in your `file` argument:\n\n{e}{RESET}")
167+
return []
146168
try:
147169
hl_dataset = _upsert_dataset(dataset=dataset, client=client)
148170
except Exception as e:
@@ -494,7 +516,7 @@ def _file_or_file_inside_hl_utility(file: File) -> File:
494516

495517

496518
def _get_file_type(file: File) -> FileType:
497-
# Determine the `type` of the `file` to Evaluate - if not `type` provided, default to `flow`
519+
"""Return the type of the File to be evaluated or default to `flow`."""
498520
try:
499521
type_ = typing.cast(FileType, file.pop("type")) # type: ignore [arg-type, misc]
500522
sys.stdout.write(
@@ -508,7 +530,7 @@ def _get_file_type(file: File) -> FileType:
508530

509531

510532
def _get_file_callable(file: File, type_: FileType) -> Optional[Callable]:
511-
# Get the `callable` from the `file` to Evaluate
533+
"""Get the callable of the File to be evaluated, or throw if None was provided for Flows."""
512534
function_ = typing.cast(Optional[Callable], file.pop("callable", None))
513535
if function_ is None:
514536
if type_ == "flow":
@@ -549,6 +571,9 @@ def _upsert_file(
549571
elif type == "evaluator":
550572
hl_file = client.evaluators.upsert(**file_dict) # type: ignore [arg-type, assignment]
551573

574+
elif type == "agent":
575+
hl_file = client.agents.upsert(**file_dict) # type: ignore [arg-type, assignment]
576+
552577
else:
553578
raise NotImplementedError(f"Unsupported File type: {type}")
554579

src/humanloop/evals/types.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
UpdateDatesetAction as UpdateDatasetAction,
2424
) # TODO: fix original type typo
2525

26-
EvaluatorDict = Union[
27-
CodeEvaluatorDict, LLMEvaluatorDict, HumanEvaluatorDict, ExternalEvaluator
28-
]
26+
EvaluatorDict = Union[CodeEvaluatorDict, LLMEvaluatorDict, HumanEvaluatorDict, ExternalEvaluator]
2927
Version = Union[FlowDict, PromptDict, ToolDict, EvaluatorDict]
3028
FileType = Literal["flow", "prompt", "tool", "evaluator"]
3129

@@ -42,7 +40,7 @@ class Identifiers(TypedDict):
4240
class File(Identifiers):
4341
"""A File on Humanloop (Flow, Prompt, Tool, Evaluator)."""
4442

45-
type: Literal["flow", "prompt"]
43+
type: Literal["flow", "prompt", "agent"]
4644
"""The type of File this callable relates to on Humanloop."""
4745
version: NotRequired[Version]
4846
"""The contents uniquely define the version of the File on Humanloop."""

0 commit comments

Comments
 (0)