deepeval 3.5.9__py3-none-any.whl → 3.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,335 +1,348 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import replace
4
- from typing import List, Any, Union, Optional
5
-
6
- try:
7
- from agents import (
8
- RunConfig,
9
- RunResult,
10
- RunResultStreaming,
11
- Runner as AgentsRunner,
12
- )
13
- from agents.agent import Agent
14
- from agents.models.interface import ModelProvider
15
- from agents.items import TResponseInputItem
16
- from agents.lifecycle import RunHooks
17
- from agents.memory import Session
18
- from agents.run import DEFAULT_MAX_TURNS
19
- from agents.run import AgentRunner
20
- from agents.run_context import TContext
21
- from agents.models.interface import Model
22
-
23
- agents_available = True
24
- except:
25
- agents_available = False
26
-
27
-
28
- def is_agents_available():
29
- if not agents_available:
30
- raise ImportError(
31
- "agents is required for this integration. Install it via your package manager"
32
- )
33
-
34
-
35
- from deepeval.tracing.tracing import Observer
36
- from deepeval.tracing.context import current_span_context, current_trace_context
37
-
38
- # Import observed provider/model helpers from our agent module
39
- from deepeval.metrics import BaseMetric
40
- from deepeval.openai_agents.agent import _ObservedModel
41
-
42
- _PATCHED_DEFAULT_GET_MODEL = False
43
-
44
-
45
- def _patch_default_agent_runner_get_model():
46
- global _PATCHED_DEFAULT_GET_MODEL
47
- if _PATCHED_DEFAULT_GET_MODEL:
48
- return
49
-
50
- original_get_model = AgentRunner._get_model
51
-
52
- @classmethod
53
- def patched_get_model(
54
- cls, agent: Agent[Any], run_config: RunConfig
55
- ) -> Model:
56
- model = original_get_model(agent, run_config)
57
-
58
- # Extract attributes from agent if it's a DeepEvalAgent
59
- llm_metrics = getattr(agent, "llm_metrics", None)
60
- llm_metric_collection = getattr(agent, "llm_metric_collection", None)
61
- confident_prompt = getattr(agent, "confident_prompt", None)
62
- model = _ObservedModel(
63
- inner=model,
64
- llm_metric_collection=llm_metric_collection,
65
- llm_metrics=llm_metrics,
66
- confident_prompt=confident_prompt,
67
- )
68
-
69
- return model
70
-
71
- # Replace the method
72
- AgentRunner._get_model = patched_get_model
73
- _PATCHED_DEFAULT_GET_MODEL = True
74
-
75
-
76
- if agents_available:
77
- _patch_default_agent_runner_get_model()
78
-
79
-
80
- class Runner(AgentsRunner):
81
-
82
- @classmethod
83
- async def run(
84
- cls,
85
- starting_agent: Agent[TContext],
86
- input: Union[str, list[TResponseInputItem]],
87
- *,
88
- context: Optional[TContext] = None,
89
- max_turns: int = DEFAULT_MAX_TURNS,
90
- hooks: Optional[RunHooks[TContext]] = None,
91
- run_config: Optional[RunConfig] = None,
92
- previous_response_id: Optional[str] = None,
93
- conversation_id: Optional[str] = None,
94
- session: Optional[Session] = None,
95
- metrics: Optional[List[BaseMetric]] = None,
96
- metric_collection: Optional[str] = None,
97
- name: Optional[str] = None,
98
- tags: Optional[List[str]] = None,
99
- metadata: Optional[dict] = None,
100
- thread_id: Optional[str] = None,
101
- user_id: Optional[str] = None,
102
- **kwargs, # backwards compatibility
103
- ) -> RunResult:
104
- is_agents_available()
105
- # _patch_default_agent_runner_get_model()
106
-
107
- with Observer(
108
- span_type="custom",
109
- metric_collection=metric_collection,
110
- metrics=metrics,
111
- func_name="run",
112
- function_kwargs={"input": input}, # also set below
113
- ) as observer:
114
- update_trace_attributes(
115
- name=name,
116
- tags=tags,
117
- metadata=metadata,
118
- thread_id=thread_id,
119
- user_id=user_id,
120
- metric_collection=metric_collection,
121
- metrics=metrics,
122
- )
123
- current_span = current_span_context.get()
124
- current_trace = current_trace_context.get()
125
- if not current_trace.input:
126
- current_trace.input = input
127
- if current_span:
128
- current_span.input = input
129
- res = await super().run(
130
- starting_agent,
131
- input,
132
- context=context,
133
- max_turns=max_turns,
134
- hooks=hooks,
135
- run_config=run_config,
136
- previous_response_id=previous_response_id,
137
- conversation_id=conversation_id,
138
- session=session,
139
- **kwargs, # backwards compatibility
140
- )
141
- current_trace_thread_id = current_trace_context.get().thread_id
142
- _output = None
143
- if current_trace_thread_id:
144
- _output = res.final_output
145
- else:
146
- _output = str(res)
147
- observer.result = _output
148
- update_trace_attributes(output=_output)
149
- return res
150
-
151
- @classmethod
152
- def run_sync(
153
- cls,
154
- starting_agent: Agent[TContext],
155
- input: Union[str, list[TResponseInputItem]],
156
- *,
157
- context: Optional[TContext] = None,
158
- max_turns: int = DEFAULT_MAX_TURNS,
159
- hooks: Optional[RunHooks[TContext]] = None,
160
- run_config: Optional[RunConfig] = None,
161
- previous_response_id: Optional[str] = None,
162
- conversation_id: Optional[str] = None,
163
- session: Optional[Session] = None,
164
- metrics: Optional[List[BaseMetric]] = None,
165
- metric_collection: Optional[str] = None,
166
- name: Optional[str] = None,
167
- tags: Optional[List[str]] = None,
168
- metadata: Optional[dict] = None,
169
- thread_id: Optional[str] = None,
170
- user_id: Optional[str] = None,
171
- **kwargs,
172
- ) -> RunResult:
173
- is_agents_available()
174
-
175
- with Observer(
176
- span_type="custom",
177
- metric_collection=metric_collection,
178
- metrics=metrics,
179
- func_name="run_sync",
180
- function_kwargs={"input": input}, # also set below
181
- ) as observer:
182
- update_trace_attributes(
183
- name=name,
184
- tags=tags,
185
- metadata=metadata,
186
- thread_id=thread_id,
187
- user_id=user_id,
188
- metric_collection=metric_collection,
189
- metrics=metrics,
190
- )
191
-
192
- current_span = current_span_context.get()
193
- current_trace = current_trace_context.get()
194
- if not current_trace.input:
195
- current_trace.input = input
196
- if current_span:
197
- current_span.input = input
198
- res = super().run_sync(
199
- starting_agent,
200
- input,
201
- context=context,
202
- max_turns=max_turns,
203
- hooks=hooks,
204
- run_config=run_config,
205
- previous_response_id=previous_response_id,
206
- conversation_id=conversation_id,
207
- session=session,
208
- **kwargs, # backwards compatibility
209
- )
210
- current_trace_thread_id = current_trace_context.get().thread_id
211
- _output = None
212
- if current_trace_thread_id:
213
- _output = res.final_output
214
- else:
215
- _output = str(res)
216
- update_trace_attributes(output=_output)
217
- observer.result = _output
218
-
219
- return res
220
-
221
- @classmethod
222
- def run_streamed(
223
- cls,
224
- starting_agent: Agent[TContext],
225
- input: Union[str, list[TResponseInputItem]],
226
- *,
227
- context: Optional[TContext] = None,
228
- max_turns: int = DEFAULT_MAX_TURNS,
229
- hooks: Optional[RunHooks[TContext]] = None,
230
- run_config: Optional[RunConfig] = None,
231
- previous_response_id: Optional[str] = None,
232
- conversation_id: Optional[str] = None,
233
- session: Optional[Session] = None,
234
- metrics: Optional[List[BaseMetric]] = None,
235
- metric_collection: Optional[str] = None,
236
- name: Optional[str] = None,
237
- tags: Optional[List[str]] = None,
238
- metadata: Optional[dict] = None,
239
- thread_id: Optional[str] = None,
240
- user_id: Optional[str] = None,
241
- **kwargs, # backwards compatibility
242
- ) -> RunResultStreaming:
243
- is_agents_available()
244
- # Manually enter observer; we'll exit when streaming finishes
245
- observer = Observer(
246
- span_type="custom",
247
- metric_collection=metric_collection,
248
- metrics=metrics,
249
- func_name="run_streamed",
250
- function_kwargs={"input": input},
251
- )
252
- observer.__enter__()
253
-
254
- update_trace_attributes(
255
- name=name,
256
- tags=tags,
257
- metadata=metadata,
258
- thread_id=thread_id,
259
- user_id=user_id,
260
- metric_collection=metric_collection,
261
- metrics=metrics,
262
- )
263
- current_trace = current_trace_context.get()
264
- if not current_trace.input:
265
- current_trace.input = input
266
-
267
- current_span = current_span_context.get()
268
- if current_span:
269
- current_span.input = input
270
-
271
- res = super().run_streamed(
272
- starting_agent,
273
- input,
274
- context=context,
275
- max_turns=max_turns,
276
- hooks=hooks,
277
- run_config=run_config,
278
- previous_response_id=previous_response_id,
279
- conversation_id=conversation_id,
280
- session=session,
281
- **kwargs, # backwards compatibility
282
- )
283
-
284
- # Runtime-patch stream_events so the observer closes only after streaming completes
285
- orig_stream_events = res.stream_events
286
-
287
- async def _patched_stream_events(self: RunResultStreaming):
288
- try:
289
- async for event in orig_stream_events():
290
- yield event
291
- observer.result = self.final_output
292
- update_trace_attributes(output=self.final_output)
293
- except Exception as e:
294
- observer.__exit__(type(e), e, e.__traceback__)
295
- raise
296
- finally:
297
- observer.__exit__(None, None, None)
298
-
299
- from types import MethodType as _MethodType
300
-
301
- res.stream_events = _MethodType(_patched_stream_events, res)
302
-
303
- return res
304
-
305
-
306
- def update_trace_attributes(
307
- input: Any = None,
308
- output: Any = None,
309
- name: str = None,
310
- tags: List[str] = None,
311
- metadata: dict = None,
312
- thread_id: str = None,
313
- user_id: str = None,
314
- metric_collection: str = None,
315
- metrics: List[BaseMetric] = None,
316
- ):
317
- current_trace = current_trace_context.get()
318
- if input:
319
- current_trace.input = input
320
- if output:
321
- current_trace.output = output
322
- if name:
323
- current_trace.name = name
324
- if tags:
325
- current_trace.tags = tags
326
- if metadata:
327
- current_trace.metadata = metadata
328
- if thread_id:
329
- current_trace.thread_id = thread_id
330
- if user_id:
331
- current_trace.user_id = user_id
332
- if metric_collection:
333
- current_trace.metric_collection = metric_collection
334
- if metrics:
335
- current_trace.metrics = metrics
1
+ # from __future__ import annotations
2
+
3
+ # from dataclasses import replace
4
+ # from typing import List, Any, Union, Optional
5
+
6
+ # try:
7
+ # from agents import (
8
+ # RunConfig,
9
+ # RunResult,
10
+ # RunResultStreaming,
11
+ # Runner as AgentsRunner,
12
+ # )
13
+ # from agents.agent import Agent
14
+ # from agents.models.interface import ModelProvider
15
+ # from agents.items import TResponseInputItem
16
+ # from agents.lifecycle import RunHooks
17
+ # from agents.memory import Session
18
+ # from agents.run import DEFAULT_MAX_TURNS
19
+ # from agents.run import AgentRunner
20
+ # from agents.run_context import TContext
21
+ # from agents.models.interface import Model
22
+ # from agents.run import SingleStepResult
23
+
24
+ # agents_available = True
25
+ # except:
26
+ # agents_available = False
27
+
28
+
29
+ # def is_agents_available():
30
+ # if not agents_available:
31
+ # raise ImportError(
32
+ # "agents is required for this integration. Install it via your package manager"
33
+ # )
34
+
35
+
36
+ # from deepeval.tracing.tracing import Observer
37
+ # from deepeval.tracing.context import current_span_context, current_trace_context
38
+ # from deepeval.tracing.utils import make_json_serializable
39
+ # from deepeval.tracing.types import AgentSpan
40
+
41
+ # # Import observed provider/model helpers from our agent module
42
+ # from deepeval.metrics import BaseMetric
43
+ # from deepeval.openai_agents.agent import _ObservedModel
44
+
45
+ # _PATCHED_DEFAULT_GET_MODEL = False
46
+ # _PATCHED_DEFAULT_RUN_SINGLE_TURN = False
47
+
48
+ # def patch_default_agent_runner_get_model():
49
+ # global _PATCHED_DEFAULT_GET_MODEL
50
+ # if _PATCHED_DEFAULT_GET_MODEL:
51
+ # return
52
+
53
+ # original_get_model_cm = AgentRunner._get_model
54
+ # try:
55
+ # original_get_model = original_get_model_cm.__func__
56
+ # except AttributeError:
57
+ # original_get_model = original_get_model_cm # fallback (non-classmethod edge case)
58
+
59
+ # def patched_get_model(cls, *args, **kwargs) -> Model:
60
+ # model = original_get_model(cls, *args, **kwargs)
61
+
62
+ # agent = kwargs.get("agent") if "agent" in kwargs else (args[0] if args else None)
63
+ # if agent is None:
64
+ # return model
65
+
66
+ # if isinstance(model, _ObservedModel):
67
+ # return model
68
+
69
+ # llm_metrics = getattr(agent, "llm_metrics", None)
70
+ # llm_metric_collection = getattr(agent, "llm_metric_collection", None)
71
+ # confident_prompt = getattr(agent, "confident_prompt", None)
72
+ # return _ObservedModel(
73
+ # inner=model,
74
+ # llm_metric_collection=llm_metric_collection,
75
+ # llm_metrics=llm_metrics,
76
+ # confident_prompt=confident_prompt,
77
+ # )
78
+
79
+ # # Preserve basic metadata and mark as patched
80
+ # patched_get_model.__name__ = original_get_model.__name__
81
+ # patched_get_model.__doc__ = original_get_model.__doc__
82
+
83
+ # AgentRunner._get_model = classmethod(patched_get_model)
84
+ # _PATCHED_DEFAULT_GET_MODEL = True
85
+
86
+
87
+ # # if agents_available:
88
+ # # patch_default_agent_run_single_turn()
89
+ # # patch_single_turn_streamed()
90
+ # # patch_default_agent_runner_get_model()
91
+
92
+
93
+ # class Runner(AgentsRunner):
94
+
95
+ # @classmethod
96
+ # async def run(
97
+ # cls,
98
+ # starting_agent: Agent[TContext],
99
+ # input: Union[str, list[TResponseInputItem]],
100
+ # *,
101
+ # context: Optional[TContext] = None,
102
+ # max_turns: int = DEFAULT_MAX_TURNS,
103
+ # hooks: Optional[RunHooks[TContext]] = None,
104
+ # run_config: Optional[RunConfig] = None,
105
+ # previous_response_id: Optional[str] = None,
106
+ # conversation_id: Optional[str] = None,
107
+ # session: Optional[Session] = None,
108
+ # metrics: Optional[List[BaseMetric]] = None,
109
+ # metric_collection: Optional[str] = None,
110
+ # name: Optional[str] = None,
111
+ # tags: Optional[List[str]] = None,
112
+ # metadata: Optional[dict] = None,
113
+ # thread_id: Optional[str] = None,
114
+ # user_id: Optional[str] = None,
115
+ # **kwargs, # backwards compatibility
116
+ # ) -> RunResult:
117
+ # is_agents_available()
118
+ # # _patch_default_agent_runner_get_model()
119
+
120
+ # with Observer(
121
+ # span_type="custom",
122
+ # metric_collection=metric_collection,
123
+ # metrics=metrics,
124
+ # func_name="run",
125
+ # function_kwargs={"input": input}, # also set below
126
+ # ) as observer:
127
+ # update_trace_attributes(
128
+ # name=name,
129
+ # tags=tags,
130
+ # metadata=metadata,
131
+ # thread_id=thread_id,
132
+ # user_id=user_id,
133
+ # metric_collection=metric_collection,
134
+ # metrics=metrics,
135
+ # )
136
+ # current_span = current_span_context.get()
137
+ # current_trace = current_trace_context.get()
138
+ # if not current_trace.input:
139
+ # current_trace.input = input
140
+ # if current_span:
141
+ # current_span.input = input
142
+ # res = await super().run(
143
+ # starting_agent,
144
+ # input,
145
+ # context=context,
146
+ # max_turns=max_turns,
147
+ # hooks=hooks,
148
+ # run_config=run_config,
149
+ # previous_response_id=previous_response_id,
150
+ # conversation_id=conversation_id,
151
+ # session=session,
152
+ # **kwargs, # backwards compatibility
153
+ # )
154
+ # current_trace_thread_id = current_trace_context.get().thread_id
155
+ # _output = None
156
+ # if current_trace_thread_id:
157
+ # _output = res.final_output
158
+ # else:
159
+ # _output = str(res)
160
+ # observer.result = _output
161
+ # update_trace_attributes(output=_output)
162
+ # return res
163
+
164
+ # @classmethod
165
+ # def run_sync(
166
+ # cls,
167
+ # starting_agent: Agent[TContext],
168
+ # input: Union[str, list[TResponseInputItem]],
169
+ # *,
170
+ # context: Optional[TContext] = None,
171
+ # max_turns: int = DEFAULT_MAX_TURNS,
172
+ # hooks: Optional[RunHooks[TContext]] = None,
173
+ # run_config: Optional[RunConfig] = None,
174
+ # previous_response_id: Optional[str] = None,
175
+ # conversation_id: Optional[str] = None,
176
+ # session: Optional[Session] = None,
177
+ # metrics: Optional[List[BaseMetric]] = None,
178
+ # metric_collection: Optional[str] = None,
179
+ # name: Optional[str] = None,
180
+ # tags: Optional[List[str]] = None,
181
+ # metadata: Optional[dict] = None,
182
+ # thread_id: Optional[str] = None,
183
+ # user_id: Optional[str] = None,
184
+ # **kwargs,
185
+ # ) -> RunResult:
186
+ # is_agents_available()
187
+
188
+ # with Observer(
189
+ # span_type="custom",
190
+ # metric_collection=metric_collection,
191
+ # metrics=metrics,
192
+ # func_name="run_sync",
193
+ # function_kwargs={"input": input}, # also set below
194
+ # ) as observer:
195
+ # update_trace_attributes(
196
+ # name=name,
197
+ # tags=tags,
198
+ # metadata=metadata,
199
+ # thread_id=thread_id,
200
+ # user_id=user_id,
201
+ # metric_collection=metric_collection,
202
+ # metrics=metrics,
203
+ # )
204
+
205
+ # current_span = current_span_context.get()
206
+ # current_trace = current_trace_context.get()
207
+ # if not current_trace.input:
208
+ # current_trace.input = input
209
+ # if current_span:
210
+ # current_span.input = input
211
+ # res = super().run_sync(
212
+ # starting_agent,
213
+ # input,
214
+ # context=context,
215
+ # max_turns=max_turns,
216
+ # hooks=hooks,
217
+ # run_config=run_config,
218
+ # previous_response_id=previous_response_id,
219
+ # conversation_id=conversation_id,
220
+ # session=session,
221
+ # **kwargs, # backwards compatibility
222
+ # )
223
+ # current_trace_thread_id = current_trace_context.get().thread_id
224
+ # _output = None
225
+ # if current_trace_thread_id:
226
+ # _output = res.final_output
227
+ # else:
228
+ # _output = str(res)
229
+ # update_trace_attributes(output=_output)
230
+ # observer.result = _output
231
+
232
+ # return res
233
+
234
+ # @classmethod
235
+ # def run_streamed(
236
+ # cls,
237
+ # starting_agent: Agent[TContext],
238
+ # input: Union[str, list[TResponseInputItem]],
239
+ # *,
240
+ # context: Optional[TContext] = None,
241
+ # max_turns: int = DEFAULT_MAX_TURNS,
242
+ # hooks: Optional[RunHooks[TContext]] = None,
243
+ # run_config: Optional[RunConfig] = None,
244
+ # previous_response_id: Optional[str] = None,
245
+ # conversation_id: Optional[str] = None,
246
+ # session: Optional[Session] = None,
247
+ # metrics: Optional[List[BaseMetric]] = None,
248
+ # metric_collection: Optional[str] = None,
249
+ # name: Optional[str] = None,
250
+ # tags: Optional[List[str]] = None,
251
+ # metadata: Optional[dict] = None,
252
+ # thread_id: Optional[str] = None,
253
+ # user_id: Optional[str] = None,
254
+ # **kwargs, # backwards compatibility
255
+ # ) -> RunResultStreaming:
256
+ # is_agents_available()
257
+ # # Manually enter observer; we'll exit when streaming finishes
258
+ # observer = Observer(
259
+ # span_type="custom",
260
+ # metric_collection=metric_collection,
261
+ # metrics=metrics,
262
+ # func_name="run_streamed",
263
+ # function_kwargs={"input": input},
264
+ # )
265
+ # observer.__enter__()
266
+
267
+ # update_trace_attributes(
268
+ # name=name,
269
+ # tags=tags,
270
+ # metadata=metadata,
271
+ # thread_id=thread_id,
272
+ # user_id=user_id,
273
+ # metric_collection=metric_collection,
274
+ # metrics=metrics,
275
+ # )
276
+ # current_trace = current_trace_context.get()
277
+ # if not current_trace.input:
278
+ # current_trace.input = input
279
+
280
+ # current_span = current_span_context.get()
281
+ # if current_span:
282
+ # current_span.input = input
283
+
284
+ # res = super().run_streamed(
285
+ # starting_agent,
286
+ # input,
287
+ # context=context,
288
+ # max_turns=max_turns,
289
+ # hooks=hooks,
290
+ # run_config=run_config,
291
+ # previous_response_id=previous_response_id,
292
+ # conversation_id=conversation_id,
293
+ # session=session,
294
+ # **kwargs, # backwards compatibility
295
+ # )
296
+
297
+ # # Runtime-patch stream_events so the observer closes only after streaming completes
298
+ # orig_stream_events = res.stream_events
299
+
300
+ # async def _patched_stream_events(self: RunResultStreaming):
301
+ # try:
302
+ # async for event in orig_stream_events():
303
+ # yield event
304
+ # observer.result = self.final_output
305
+ # update_trace_attributes(output=self.final_output)
306
+ # except Exception as e:
307
+ # observer.__exit__(type(e), e, e.__traceback__)
308
+ # raise
309
+ # finally:
310
+ # observer.__exit__(None, None, None)
311
+
312
+ # from types import MethodType as _MethodType
313
+
314
+ # res.stream_events = _MethodType(_patched_stream_events, res)
315
+
316
+ # return res
317
+
318
+
319
+ # def update_trace_attributes(
320
+ # input: Any = None,
321
+ # output: Any = None,
322
+ # name: str = None,
323
+ # tags: List[str] = None,
324
+ # metadata: dict = None,
325
+ # thread_id: str = None,
326
+ # user_id: str = None,
327
+ # metric_collection: str = None,
328
+ # metrics: List[BaseMetric] = None,
329
+ # ):
330
+ # current_trace = current_trace_context.get()
331
+ # if input:
332
+ # current_trace.input = input
333
+ # if output:
334
+ # current_trace.output = output
335
+ # if name:
336
+ # current_trace.name = name
337
+ # if tags:
338
+ # current_trace.tags = tags
339
+ # if metadata:
340
+ # current_trace.metadata = metadata
341
+ # if thread_id:
342
+ # current_trace.thread_id = thread_id
343
+ # if user_id:
344
+ # current_trace.user_id = user_id
345
+ # if metric_collection:
346
+ # current_trace.metric_collection = metric_collection
347
+ # if metrics:
348
+ # current_trace.metrics = metrics