|
13 | 13 | from ddtrace.contrib.internal.trace_utils import unwrap
|
14 | 14 | from ddtrace.contrib.internal.trace_utils import wrap
|
15 | 15 | import ddtrace.internal.logger as ddlogger
|
| 16 | +from ddtrace.internal.utils import get_argument_value |
16 | 17 |
|
17 | 18 |
|
18 | 19 | logger = ddlogger.get_logger(__name__)
|
@@ -164,28 +165,57 @@ def _handle_agent_action_result(client: AIGuardClient, result, kwargs):
|
164 | 165 |
|
165 | 166 |
|
166 | 167 | def _langchain_chatmodel_generate_before(client: AIGuardClient, message_lists):
|
167 |
| - from langchain_core.messages import HumanMessage |
168 |
| - |
169 | 168 | for messages in message_lists:
|
170 |
| - # only call evaluator when the last message is an actual user prompt |
171 |
| - if len(messages) > 0 and isinstance(messages[-1], HumanMessage): |
172 |
| - history = _convert_messages(messages) |
173 |
| - prompt = history.pop(-1) |
174 |
| - try: |
175 |
| - if not client.evaluate_prompt(prompt["role"], prompt["content"], history=history): # type: ignore[typeddict-item] |
176 |
| - return AIGuardAbortError() |
177 |
| - except AIGuardAbortError as e: |
178 |
| - return e |
179 |
| - except Exception: |
180 |
| - logger.debug("Failed to evaluate chat model prompt", exc_info=True) |
| 169 | + result = _evaluate_langchain_messages(client, messages) |
| 170 | + if result: |
| 171 | + return result |
| 172 | + return None |
181 | 173 |
|
182 | 174 |
|
183 | 175 | def _langchain_llm_generate_before(client: AIGuardClient, prompts):
|
184 | 176 | for prompt in prompts:
|
| 177 | + result = _evaluate_langchain_prompt(client, prompt) |
| 178 | + if result: |
| 179 | + return result |
| 180 | + return None |
| 181 | + |
| 182 | + |
| 183 | +def _langchain_chatmodel_stream_before(client: AIGuardClient, instance, args, kwargs): |
| 184 | + input_arg = get_argument_value(args, kwargs, 0, "input") |
| 185 | + messages = instance._convert_input(input_arg).to_messages() |
| 186 | + return _evaluate_langchain_messages(client, messages) |
| 187 | + |
| 188 | + |
| 189 | +def _langchain_llm_stream_before(client: AIGuardClient, instance, args, kwargs): |
| 190 | + input_arg = get_argument_value(args, kwargs, 0, "input") |
| 191 | + prompt = instance._convert_input(input_arg).to_string() |
| 192 | + return _evaluate_langchain_prompt(client, prompt) |
| 193 | + |
| 194 | + |
| 195 | +def _evaluate_langchain_messages(client: AIGuardClient, messages): |
| 196 | + from langchain_core.messages import HumanMessage |
| 197 | + |
| 198 | + # only call evaluator when the last message is an actual user prompt |
| 199 | + if len(messages) > 0 and isinstance(messages[-1], HumanMessage): |
| 200 | + history = _convert_messages(messages) |
| 201 | + prompt = history.pop(-1) |
185 | 202 | try:
|
186 |
| - if not client.evaluate_prompt("user", prompt): |
| 203 | + role, content = (prompt["role"], prompt["content"]) # type: ignore[typeddict-item] |
| 204 | + if not client.evaluate_prompt(role, content, history=history): |
187 | 205 | return AIGuardAbortError()
|
188 | 206 | except AIGuardAbortError as e:
|
189 | 207 | return e
|
190 | 208 | except Exception:
|
191 |
| - logger.debug("Failed to evaluate llm prompt", exc_info=True) |
| 209 | + logger.debug("Failed to evaluate chat model prompt", exc_info=True) |
| 210 | + return None |
| 211 | + |
| 212 | + |
| 213 | +def _evaluate_langchain_prompt(client: AIGuardClient, prompt): |
| 214 | + try: |
| 215 | + if not client.evaluate_prompt("user", prompt): |
| 216 | + return AIGuardAbortError() |
| 217 | + except AIGuardAbortError as e: |
| 218 | + return e |
| 219 | + except Exception: |
| 220 | + logger.debug("Failed to evaluate llm prompt", exc_info=True) |
| 221 | + return None |
0 commit comments