Skip to content

Commit d703478

Browse files
committed
refactor overloads
1 parent 6318918 commit d703478

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

src/humanloop/overload.py

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import inspect
22
import logging
33
import types
4-
from typing import TypeVar, Union, Literal
4+
from typing import TypeVar, Union, Literal, Optional
55
from pathlib import Path
66
from humanloop.context import (
77
get_decorator_context,
@@ -117,7 +117,7 @@ def _overload_call(self, **kwargs) -> PromptCallResponse:
117117
logger.info(f"Calling inner overload")
118118
response = self._call(**kwargs)
119119
except Exception as e:
120-
# Re-raising as HumanloopDecoratorError so the decorators don't catch it
120+
# Re-raising as HumanloopRuntimeError so the decorators don't catch it
121121
raise HumanloopRuntimeError from e
122122

123123
return response
@@ -126,55 +126,75 @@ def _overload_call(self, **kwargs) -> PromptCallResponse:
126126
client.call = types.MethodType(_overload_call, client) # type: ignore [assignment]
127127
return client
128128

129+
def _get_file_type_from_client(client: Union[PromptsClient, AgentsClient]) -> FileType:
130+
"""Get the file type based on the client type."""
131+
if isinstance(client, PromptsClient):
132+
return "prompt"
133+
elif isinstance(client, AgentsClient):
134+
return "agent"
135+
else:
136+
raise ValueError(f"Unsupported client type: {type(client)}")
137+
138+
def _handle_local_file(path: str, file_type: FileType) -> Optional[str]:
139+
"""Handle reading from a local file if it exists.
140+
141+
Args:
142+
path: The path to the file
143+
file_type: The type of file ("prompt" or "agent")
144+
145+
Returns:
146+
The file content if found, None otherwise
147+
"""
148+
try:
149+
# Construct path to local file
150+
local_path = Path("humanloop") / path # FLAG: ensure that when passing the path back to remote, it's using forward slashes
151+
# Add appropriate extension
152+
local_path = local_path.parent / f"{local_path.stem}.{file_type}"
153+
154+
if local_path.exists():
155+
# Read the file content
156+
with open(local_path) as f:
157+
file_content = f.read()
158+
logger.debug(f"Using local file content from {local_path}")
159+
return file_content
160+
else:
161+
logger.warning(f"Local file not found: {local_path}, falling back to API")
162+
return None
163+
except Exception as e:
164+
logger.error(f"Error reading local file: {e}, falling back to API")
165+
return None
166+
129167
def overload_with_local_files(
130168
client: Union[PromptsClient, AgentsClient],
131169
use_local_files: bool,
132170
) -> Union[PromptsClient, AgentsClient]:
133-
"""Overload call to handle local files when use_local_files is True.
171+
"""Overload call and log methods to handle local files when use_local_files is True.
134172
135173
Args:
136174
client: The client to overload (PromptsClient or AgentsClient)
137175
use_local_files: Whether to use local files
138-
file_type: Type of file ("prompt" or "agent")
139176
"""
140177
original_call = client._call if hasattr(client, '_call') else client.call
141178
original_log = client._log if hasattr(client, '_log') else client.log
142-
# get file type from client type
143-
file_type: FileType
144-
if isinstance(client, PromptsClient):
145-
file_type = "prompt"
146-
elif isinstance(client, AgentsClient):
147-
file_type = "agent"
148-
else:
149-
raise ValueError(f"Unsupported client type: {type(client)}")
179+
file_type = _get_file_type_from_client(client)
150180

151181
def _overload(self, function_name: str, **kwargs) -> PromptCallResponse:
182+
# Handle local files if enabled
152183
if use_local_files and "path" in kwargs:
153-
try:
154-
# Construct path to local file
155-
local_path = Path("humanloop") / kwargs["path"] # FLAG: ensure that when passing the path back to remote, it's using forward slashes
156-
# Add appropriate extension
157-
local_path = local_path.parent / f"{local_path.stem}.{file_type}"
158-
159-
if local_path.exists():
160-
# Read the file content
161-
with open(local_path) as f:
162-
file_content = f.read()
163-
164-
kwargs[file_type] = file_content # "prompt" or "agent" # TODO: raise warning if kernel passed in
165-
166-
logger.debug(f"Using local file content from {local_path}")
167-
else:
168-
logger.warning(f"Local file not found: {local_path}, falling back to API")
169-
except Exception as e:
170-
logger.error(f"Error reading local file: {e}, falling back to API")
184+
file_content = _handle_local_file(kwargs["path"], file_type)
185+
if file_content is not None:
186+
kwargs[file_type] = file_content
171187

172-
if function_name == "call":
173-
return original_call(**kwargs)
174-
elif function_name == "log":
175-
return original_log(**kwargs)
176-
else:
177-
raise ValueError(f"Unsupported function name: {function_name}")
188+
try:
189+
if function_name == "call":
190+
return original_call(**kwargs)
191+
elif function_name == "log":
192+
return original_log(**kwargs)
193+
else:
194+
raise ValueError(f"Unsupported function name: {function_name}")
195+
except Exception as e:
196+
# Re-raising as HumanloopRuntimeError so the decorators don't catch it
197+
raise HumanloopRuntimeError from e
178198

179199
def _overload_call(self, **kwargs) -> PromptCallResponse:
180200
return _overload(self, "call", **kwargs)

0 commit comments

Comments
 (0)