Skip to content

Commit 152fbfa

Browse files
committed
overload log operation to use local files when relevant
1 parent 2eb8ec1 commit 152fbfa

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

src/humanloop/client.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from humanloop.evals.types import Dataset, Evaluator, EvaluatorCheck, File
1414

1515
from humanloop.base_client import AsyncBaseHumanloop, BaseHumanloop
16-
from humanloop.overload import overload_call, overload_log, overload_call_with_local_files
16+
from humanloop.overload import overload_call, overload_log, overload_with_local_files
1717
from humanloop.decorators.flow import flow as flow_decorator_factory
1818
from humanloop.decorators.prompt import prompt_decorator_factory
1919
from humanloop.decorators.tool import tool_decorator_factory as tool_decorator_factory
@@ -77,6 +77,7 @@ class ExtendedPromptsClient(PromptsClient):
7777
"""
7878

7979
populate_template = staticmethod(populate_template) # type: ignore [assignment]
80+
load = staticmethod(load)
8081

8182

8283
class Humanloop(BaseHumanloop):
@@ -130,11 +131,11 @@ def __init__(
130131
# and the @flow decorator providing the trace_id
131132
self.prompts = overload_log(client=self.prompts)
132133
self.prompts = overload_call(client=self.prompts)
133-
self.prompts = overload_call_with_local_files(
134+
self.prompts = overload_with_local_files(
134135
client=self.prompts,
135136
use_local_files=self.use_local_files
136137
)
137-
self.agents = overload_call_with_local_files(
138+
self.agents = overload_with_local_files(
138139
client=self.agents,
139140
use_local_files=self.use_local_files
140141
)
@@ -393,4 +394,4 @@ class AsyncHumanloop(AsyncBaseHumanloop):
393394
TODO: Add custom evaluation utilities for async case.
394395
"""
395396

396-
pass
397+
pass

src/humanloop/overload.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def _overload_call(self, **kwargs) -> PromptCallResponse:
126126
client.call = types.MethodType(_overload_call, client) # type: ignore [assignment]
127127
return client
128128

129-
def overload_call_with_local_files(
129+
def overload_with_local_files(
130130
client: Union[PromptsClient, AgentsClient],
131131
use_local_files: bool,
132132
) -> Union[PromptsClient, AgentsClient]:
@@ -138,6 +138,7 @@ def overload_call_with_local_files(
138138
file_type: Type of file ("prompt" or "agent")
139139
"""
140140
original_call = client._call if hasattr(client, '_call') else client.call
141+
original_log = client._log if hasattr(client, '_log') else client.log
141142
# get file type from client type
142143
file_type: FileType
143144
if isinstance(client, PromptsClient):
@@ -147,11 +148,11 @@ def overload_call_with_local_files(
147148
else:
148149
raise ValueError(f"Unsupported client type: {type(client)}")
149150

150-
def _overload_call(self, **kwargs) -> PromptCallResponse:
151+
def _overload(self, function_name: str, **kwargs) -> PromptCallResponse:
151152
if use_local_files and "path" in kwargs:
152153
try:
153154
# Construct path to local file
154-
local_path = Path("humanloop") / kwargs["path"]
155+
local_path = Path("humanloop") / kwargs["path"] # FLAG: ensure that when passing the path back to remote, it's using forward slashes
155156
# Add appropriate extension
156157
local_path = local_path.parent / f"{local_path.stem}.{file_type}"
157158

@@ -160,15 +161,27 @@ def _overload_call(self, **kwargs) -> PromptCallResponse:
160161
with open(local_path) as f:
161162
file_content = f.read()
162163

163-
kwargs[file_type] = file_content # "prompt" or "agent" # TODO: raise warning if kernel passed in
164+
kwargs[file_type] = file_content # "prompt" or "agent" # TODO: raise warning if kernel passed in
164165

165166
logger.debug(f"Using local file content from {local_path}")
166167
else:
167168
logger.warning(f"Local file not found: {local_path}, falling back to API")
168169
except Exception as e:
169170
logger.error(f"Error reading local file: {e}, falling back to API")
170171

171-
return original_call(**kwargs)
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}")
178+
179+
def _overload_call(self, **kwargs) -> PromptCallResponse:
180+
return _overload(self, "call", **kwargs)
181+
182+
def _overload_log(self, **kwargs) -> PromptCallResponse:
183+
return _overload(self, "log", **kwargs)
172184

173185
client.call = types.MethodType(_overload_call, client)
186+
client.log = types.MethodType(_overload_log, client)
174187
return client

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def api_keys() -> APIKeys:
194194
def humanloop_client(api_keys: APIKeys) -> Humanloop:
195195
return Humanloop(
196196
api_key=api_keys.humanloop,
197-
base_url="https://neostaging.humanloop.ml/v5/",
197+
base_url="http://localhost:80/v5/",
198198
)
199199

200200

0 commit comments

Comments
 (0)