1+ from collections import defaultdict
12import inspect
23import logging
34import types
@@ -99,10 +100,13 @@ def _overload_log(
99100
100101
101102def overload_call (client : PromptsClient ) -> PromptsClient :
102- client ._call = client .call # type: ignore [attr-defined]
103+ if not hasattr (client , "_overloads" ):
104+ client ._overloads = defaultdict (list ) # type: ignore [attr-defined]
105+ if len (client ._overloads ["call" ]) == 0 : # type: ignore [attr-defined]
106+ client ._overloads ["call" ].append (client .call ) # type: ignore [attr-defined]
103107
104108 def _overload_call (self , ** kwargs ) -> PromptCallResponse :
105- # None if not logging inside a decorator
109+ # trace_id is None if logging outside a decorator
106110 trace_id = get_trace_id ()
107111 if trace_id is not None :
108112 if "trace_parent_id" in kwargs :
@@ -116,14 +120,13 @@ def _overload_call(self, **kwargs) -> PromptCallResponse:
116120 }
117121
118122 try :
119- response = self . _call (** kwargs )
123+ response = client . _overloads [ "call" ][ 0 ] (** kwargs ) # type: ignore [attr-defined]
120124 except Exception as e :
121125 # Re-raising as HumanloopRuntimeError so the decorators don't catch it
122126 raise HumanloopRuntimeError from e
123127
124128 return response
125129
126- # Replace the original log method with the overloaded one
127130 client .call = types .MethodType (_overload_call , client ) # type: ignore [assignment]
128131 return client
129132
@@ -168,13 +171,34 @@ def overload_with_local_files(
168171 Raises:
169172 HumanloopRuntimeError: If use_local_files is True and local file cannot be accessed
170173 """
171- original_call = client ._call if hasattr (client , "_call" ) else client .call
172- original_log = client ._log if hasattr (client , "_log" ) else client .log
174+ if not hasattr (client , "_overloads" ):
175+ client ._overloads = defaultdict (list ) # type: ignore [union-attr]
176+ # If the method has been overloaded, don't re-add the method
177+ if isinstance (client , PromptsClient ):
178+ if len (client ._overloads ["call" ]) == 1 : # type: ignore [attr-defined]
179+ client ._overloads ["call" ].append (client .call ) # type: ignore [attr-defined]
180+ else :
181+ raise RuntimeError (f"Unexpected overload order of operations for { client } .call" )
182+ elif isinstance (client , AgentsClient ):
183+ if len (client ._overloads ["call" ]) == 0 :
184+ client ._overloads ["call" ].append (client .call )
185+ else :
186+ raise RuntimeError (f"Unexpected overload order of operations for { client } .call" )
187+ else :
188+ raise NotImplementedError (f"Unsupported client type: { type (client )} " )
189+ if len (client ._overloads ["log" ]) == 0 :
190+ client ._overloads ["log" ].append (client .log )
191+ else :
192+ raise RuntimeError (f"Unexpected overload order of operations for { client } .log" )
193+
173194 file_type = _get_file_type_from_client (client )
174195
175196 def _overload (self , function_name : str , ** kwargs ) -> PromptCallResponse :
176197 if "id" in kwargs and "path" in kwargs :
177- raise HumanloopRuntimeError (f"Can only specify one of `id` or `path` when { function_name } ing a { file_type } " )
198+ raise HumanloopRuntimeError (
199+ "Can only specify one of `id` or `path` when "
200+ f"{ 'logging' if function_name == 'log' else 'calling' } a { file_type } "
201+ )
178202 # Handle local files if enabled
179203 if use_local_files and "path" in kwargs :
180204 # Check if version_id or environment is specified
@@ -204,9 +228,9 @@ def _overload(self, function_name: str, **kwargs) -> PromptCallResponse:
204228
205229 try :
206230 if function_name == "call" :
207- return original_call (** kwargs )
231+ return client . _overloads [ "call" ][ 1 ] (** kwargs ) # type: ignore [attr-defined, union-attr]
208232 elif function_name == "log" :
209- return original_log (** kwargs )
233+ return client . _overloads [ "log" ][ 0 ] (** kwargs ) # type: ignore [attr-defined, union-attr]
210234 else :
211235 raise ValueError (f"Unsupported function name: { function_name } " )
212236 except Exception as e :
0 commit comments