freeplay 0.3.23__py3-none-any.whl → 0.3.24a0__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.
- freeplay/__init__.py +2 -1
- freeplay/model.py +6 -0
- freeplay/resources/recordings.py +2 -6
- freeplay/resources/sessions.py +5 -2
- freeplay/resources/test_runs.py +34 -4
- freeplay/support.py +33 -14
- {freeplay-0.3.23.dist-info → freeplay-0.3.24a0.dist-info}/METADATA +1 -1
- {freeplay-0.3.23.dist-info → freeplay-0.3.24a0.dist-info}/RECORD +11 -11
- {freeplay-0.3.23.dist-info → freeplay-0.3.24a0.dist-info}/LICENSE +0 -0
- {freeplay-0.3.23.dist-info → freeplay-0.3.24a0.dist-info}/WHEEL +0 -0
- {freeplay-0.3.23.dist-info → freeplay-0.3.24a0.dist-info}/entry_points.txt +0 -0
freeplay/__init__.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from .freeplay import Freeplay
|
2
2
|
from .resources.prompts import PromptInfo
|
3
|
-
from .
|
3
|
+
from .model import TestRunInfo
|
4
|
+
from .resources.recordings import CallInfo, ResponseInfo, RecordPayload, UsageTokens
|
4
5
|
from .resources.sessions import SessionInfo, TraceInfo
|
5
6
|
from .support import CustomMetadata
|
6
7
|
|
freeplay/model.py
CHANGED
freeplay/resources/recordings.py
CHANGED
@@ -9,11 +9,12 @@ from requests import HTTPError
|
|
9
9
|
from freeplay import api_support
|
10
10
|
from freeplay.errors import FreeplayClientError, FreeplayError
|
11
11
|
from freeplay.llm_parameters import LLMParameters
|
12
|
-
from freeplay.model import InputVariables, OpenAIFunctionCall
|
12
|
+
from freeplay.model import InputVariables, OpenAIFunctionCall, TestRunInfo
|
13
13
|
from freeplay.resources.prompts import PromptInfo, MediaInputMap, MediaInput, MediaInputUrl
|
14
14
|
from freeplay.resources.sessions import SessionInfo, TraceInfo
|
15
15
|
from freeplay.support import CallSupport
|
16
16
|
|
17
|
+
|
17
18
|
logger = logging.getLogger(__name__)
|
18
19
|
|
19
20
|
|
@@ -65,11 +66,6 @@ class ResponseInfo:
|
|
65
66
|
response_tokens: Optional[int] = None
|
66
67
|
|
67
68
|
|
68
|
-
@dataclass
|
69
|
-
class TestRunInfo:
|
70
|
-
test_run_id: str
|
71
|
-
test_case_id: str
|
72
|
-
|
73
69
|
|
74
70
|
@dataclass
|
75
71
|
class RecordPayload:
|
freeplay/resources/sessions.py
CHANGED
@@ -3,6 +3,7 @@ from dataclasses import dataclass
|
|
3
3
|
from typing import Optional, Dict, Union
|
4
4
|
|
5
5
|
from freeplay.errors import FreeplayClientError
|
6
|
+
from freeplay.model import TestRunInfo
|
6
7
|
from freeplay.support import CallSupport, CustomMetadata
|
7
8
|
|
8
9
|
|
@@ -40,7 +41,8 @@ class TraceInfo:
|
|
40
41
|
self,
|
41
42
|
project_id: str,
|
42
43
|
output: str,
|
43
|
-
eval_results: Optional[Dict[str, Union[bool, float]]] = None
|
44
|
+
eval_results: Optional[Dict[str, Union[bool, float]]] = None,
|
45
|
+
test_run_info: Optional[TestRunInfo] = None
|
44
46
|
) -> None:
|
45
47
|
if self.input is None:
|
46
48
|
raise FreeplayClientError("Input must be set before recording output")
|
@@ -52,7 +54,8 @@ class TraceInfo:
|
|
52
54
|
output,
|
53
55
|
agent_name=self.agent_name,
|
54
56
|
custom_metadata=self.custom_metadata,
|
55
|
-
eval_results=eval_results
|
57
|
+
eval_results=eval_results,
|
58
|
+
test_run_info=test_run_info
|
56
59
|
)
|
57
60
|
|
58
61
|
|
freeplay/resources/test_runs.py
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from typing import List, Optional, Dict
|
3
3
|
|
4
|
-
from freeplay.model import InputVariables
|
5
|
-
from freeplay.resources.recordings import TestRunInfo
|
4
|
+
from freeplay.model import InputVariables, TestRunInfo
|
6
5
|
from freeplay.support import CallSupport, SummaryStatistics
|
7
6
|
|
8
7
|
|
@@ -20,20 +19,45 @@ class TestCase:
|
|
20
19
|
self.output = output
|
21
20
|
self.history = history
|
22
21
|
|
22
|
+
class TraceTestCase:
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
test_case_id: str,
|
26
|
+
input: str,
|
27
|
+
output: Optional[str],
|
28
|
+
):
|
29
|
+
self.id = test_case_id
|
30
|
+
self.input = input
|
31
|
+
self.output = output
|
23
32
|
|
24
33
|
@dataclass
|
25
34
|
class TestRun:
|
26
35
|
def __init__(
|
27
36
|
self,
|
28
37
|
test_run_id: str,
|
29
|
-
test_cases: List[TestCase]
|
38
|
+
test_cases: List[TestCase] = [],
|
39
|
+
trace_test_cases: List[TraceTestCase] = []
|
30
40
|
):
|
31
41
|
self.test_run_id = test_run_id
|
32
42
|
self.test_cases = test_cases
|
43
|
+
self.trace_test_cases = trace_test_cases
|
44
|
+
|
45
|
+
def __must_not_be_both_trace_and_completion(self) -> None:
|
46
|
+
if self.test_cases and len(self.test_cases) > 0 and self.trace_test_cases and len(self.trace_test_cases) > 0:
|
47
|
+
raise ValueError("Test case and trace test case cannot both be present")
|
33
48
|
|
34
49
|
def get_test_cases(self) -> List[TestCase]:
|
50
|
+
self.__must_not_be_both_trace_and_completion()
|
51
|
+
if len(self.trace_test_cases) > 0:
|
52
|
+
raise ValueError("Completion test cases are not present. Please use get_trace_test_cases() instead.")
|
35
53
|
return self.test_cases
|
36
54
|
|
55
|
+
def get_trace_test_cases(self) -> List[TraceTestCase]:
|
56
|
+
self.__must_not_be_both_trace_and_completion()
|
57
|
+
if len(self.test_cases) > 0:
|
58
|
+
raise ValueError("Trace test cases are not present. Please use get_test_cases() instead.")
|
59
|
+
return self.trace_test_cases
|
60
|
+
|
37
61
|
def get_test_run_info(self, test_case_id: str) -> TestRunInfo:
|
38
62
|
return TestRunInfo(self.test_run_id, test_case_id)
|
39
63
|
|
@@ -75,8 +99,14 @@ class TestRuns:
|
|
75
99
|
history=test_case.history)
|
76
100
|
for test_case in test_run.test_cases
|
77
101
|
]
|
102
|
+
trace_test_cases = [
|
103
|
+
TraceTestCase(test_case_id=test_case.id,
|
104
|
+
input=test_case.input,
|
105
|
+
output=test_case.output)
|
106
|
+
for test_case in test_run.trace_test_cases
|
107
|
+
]
|
78
108
|
|
79
|
-
return TestRun(test_run.test_run_id, test_cases)
|
109
|
+
return TestRun(test_run.test_run_id, test_cases, trace_test_cases)
|
80
110
|
|
81
111
|
def get(self, project_id: str, test_run_id: str) -> TestRunResults:
|
82
112
|
test_run_results = self.call_support.get_test_run_results(project_id, test_run_id)
|
freeplay/support.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
from dataclasses import dataclass, field
|
1
|
+
from dataclasses import dataclass, field, asdict
|
2
2
|
from json import JSONEncoder
|
3
3
|
from typing import Optional, Dict, Any, List, Union, Literal
|
4
4
|
|
5
5
|
from freeplay import api_support
|
6
6
|
from freeplay.api_support import try_decode
|
7
7
|
from freeplay.errors import freeplay_response_error, FreeplayServerError
|
8
|
-
from freeplay.model import InputVariables, FeedbackValue, NormalizedMessage
|
8
|
+
from freeplay.model import InputVariables, FeedbackValue, NormalizedMessage, TestRunInfo
|
9
9
|
|
10
10
|
CustomMetadata = Optional[Dict[str, Union[str, int, float, bool]]]
|
11
11
|
|
@@ -83,22 +83,38 @@ class PromptTemplateEncoder(JSONEncoder):
|
|
83
83
|
|
84
84
|
class TestCaseTestRunResponse:
|
85
85
|
def __init__(self, test_case: Dict[str, Any]):
|
86
|
-
self.variables: InputVariables = test_case['variables']
|
87
86
|
self.id: str = test_case['test_case_id']
|
87
|
+
self.variables: InputVariables = test_case['variables']
|
88
88
|
self.output: Optional[str] = test_case.get('output')
|
89
89
|
self.history: Optional[List[Dict[str, Any]]] = test_case.get('history')
|
90
|
+
self.custom_metadata: Optional[Dict[str, str]] = test_case.get('custom_metadata')
|
90
91
|
|
92
|
+
class TraceTestCaseTestRunResponse:
|
93
|
+
def __init__(self, test_case: Dict[str, Any]):
|
94
|
+
self.id: str = test_case['test_case_id']
|
95
|
+
self.input: str = test_case['input']
|
96
|
+
self.output: Optional[str] = test_case.get('output')
|
97
|
+
self.custom_metadata: Optional[Dict[str, str]] = test_case.get('custom_metadata')
|
91
98
|
|
92
99
|
class TestRunResponse:
|
93
100
|
def __init__(
|
94
101
|
self,
|
95
102
|
test_run_id: str,
|
96
|
-
test_cases: List[Dict[str, Any]]
|
103
|
+
test_cases: Optional[List[Dict[str, Any]]],
|
104
|
+
trace_test_cases: Optional[List[Dict[str, Any]]]
|
97
105
|
):
|
106
|
+
if test_cases and trace_test_cases:
|
107
|
+
raise ValueError("Test cases and trace test cases cannot both be present.")
|
108
|
+
|
98
109
|
self.test_cases = [
|
99
110
|
TestCaseTestRunResponse(test_case)
|
100
|
-
for test_case in test_cases
|
111
|
+
for test_case in (test_cases or []) if test_case is not None
|
112
|
+
]
|
113
|
+
self.trace_test_cases = [
|
114
|
+
TraceTestCaseTestRunResponse(test_case)
|
115
|
+
for test_case in (trace_test_cases or []) if test_case is not None
|
101
116
|
]
|
117
|
+
|
102
118
|
self.test_run_id = test_run_id
|
103
119
|
|
104
120
|
|
@@ -267,7 +283,7 @@ class CallSupport:
|
|
267
283
|
|
268
284
|
json_dom = response.json()
|
269
285
|
|
270
|
-
return TestRunResponse(json_dom['test_run_id'], json_dom['test_cases'])
|
286
|
+
return TestRunResponse(json_dom['test_run_id'], json_dom['test_cases'], json_dom['trace_test_cases'])
|
271
287
|
|
272
288
|
def get_test_run_results(
|
273
289
|
self,
|
@@ -299,18 +315,21 @@ class CallSupport:
|
|
299
315
|
output: str,
|
300
316
|
agent_name: Optional[str] = None,
|
301
317
|
custom_metadata: CustomMetadata = None,
|
302
|
-
eval_results: Optional[Dict[str, Union[bool, float]]] = None
|
318
|
+
eval_results: Optional[Dict[str, Union[bool, float]]] = None,
|
319
|
+
test_run_info: Optional[TestRunInfo] = None
|
303
320
|
) -> None:
|
321
|
+
payload = {
|
322
|
+
'agent_name': agent_name,
|
323
|
+
'input': input,
|
324
|
+
'output': output,
|
325
|
+
'custom_metadata': custom_metadata,
|
326
|
+
'eval_results': eval_results,
|
327
|
+
'test_run_info': asdict(test_run_info) if test_run_info else None
|
328
|
+
}
|
304
329
|
response = api_support.post_raw(
|
305
330
|
self.freeplay_api_key,
|
306
331
|
f'{self.api_base}/v2/projects/{project_id}/sessions/{session_id}/traces/id/{trace_id}',
|
307
|
-
|
308
|
-
'agent_name': agent_name,
|
309
|
-
'input': input,
|
310
|
-
'output': output,
|
311
|
-
'custom_metadata': custom_metadata,
|
312
|
-
'eval_results': eval_results,
|
313
|
-
}
|
332
|
+
payload
|
314
333
|
)
|
315
334
|
if response.status_code != 201:
|
316
335
|
raise freeplay_response_error('Error while recording trace.', response)
|
@@ -1,23 +1,23 @@
|
|
1
|
-
freeplay/__init__.py,sha256=
|
1
|
+
freeplay/__init__.py,sha256=ljXF0vHC3oGgk-vLyJFawr7MZKOj_ExYJJsVdrpqZoM,482
|
2
2
|
freeplay/api_support.py,sha256=Kn2x3g6yloHQl3NwFRjbZE9BnIh7d1sgwGwC0mHuvw4,2483
|
3
3
|
freeplay/errors.py,sha256=vwotUBldxDzREZOmLUeoiDoZjcvDwgH1AMwKBLhLooE,807
|
4
4
|
freeplay/freeplay.py,sha256=J04-erDD6rI2SAje_Nsf3x5Qx-Z6p8gQvGrMRHFWoD4,1602
|
5
5
|
freeplay/freeplay_cli.py,sha256=lmdsYwzdpWmUKHz_ieCzB-e6j1EnDHlVw3XIEyP_NEk,3460
|
6
6
|
freeplay/llm_parameters.py,sha256=bQbfuC8EICF0XMZQa5pwI3FkQqxmCUVqHO3gYHy3Tg8,898
|
7
|
-
freeplay/model.py,sha256=
|
7
|
+
freeplay/model.py,sha256=GI3qPRouwdrBFOPBrcQFt5O0chtlSNvl8jAstePuYlA,1480
|
8
8
|
freeplay/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
9
|
freeplay/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
freeplay/resources/adapters.py,sha256=6ZAPpoLeOkUkV1s9VNQNsYrnupV0-sy11zFfKfctM1Y,9296
|
11
11
|
freeplay/resources/customer_feedback.py,sha256=bw8MfEOKbGgn4FOyvcADrcs9GhcpNXNTgxKjBjIzywE,899
|
12
12
|
freeplay/resources/prompts.py,sha256=mnL1VscMGM7D4ulGf3CBGQKdsSj8I5Wf_6nJEYa7mZI,23353
|
13
|
-
freeplay/resources/recordings.py,sha256=
|
14
|
-
freeplay/resources/sessions.py,sha256=
|
13
|
+
freeplay/resources/recordings.py,sha256=V8KAPWnYAQ2-gqwyAJveD8a_AaBPYT32N_xbPU4S27M,9153
|
14
|
+
freeplay/resources/sessions.py,sha256=dZtd9nq2nH8pmXxQOJitBnN5Jl3kjggDItDcjC69TYo,3883
|
15
15
|
freeplay/resources/test_cases.py,sha256=nXL_976RwSJDT6OWDM4GEzbcOzcGkJ9ulvb0XOzCRDM,2240
|
16
|
-
freeplay/resources/test_runs.py,sha256=
|
17
|
-
freeplay/support.py,sha256=
|
16
|
+
freeplay/resources/test_runs.py,sha256=snaNOqgwMiIKTRMw2nIGEficVrBdRX6O_zKuGW94k68,3969
|
17
|
+
freeplay/support.py,sha256=AcaG6vkmI9r6_eNFoX29eTh4MRjdb4To5wIEm78v7IE,13299
|
18
18
|
freeplay/utils.py,sha256=Xvt4mNLXLL7E6MI2hTuDLV5cl5Y83DgdjCZSyDGMjR0,3187
|
19
|
-
freeplay-0.3.
|
20
|
-
freeplay-0.3.
|
21
|
-
freeplay-0.3.
|
22
|
-
freeplay-0.3.
|
23
|
-
freeplay-0.3.
|
19
|
+
freeplay-0.3.24a0.dist-info/LICENSE,sha256=_jzIw45hB1XHGxiQ8leZ0GH_X7bR_a8qgxaqnHbCUOo,1064
|
20
|
+
freeplay-0.3.24a0.dist-info/METADATA,sha256=t-Xi5FKYXUv59Wj59dxDar6pXokD8OxFY6EvYbuGSo8,1663
|
21
|
+
freeplay-0.3.24a0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
22
|
+
freeplay-0.3.24a0.dist-info/entry_points.txt,sha256=32s3rf2UUCqiJT4jnClEXZhdXlvl30uwpcxz-Gsy4UU,54
|
23
|
+
freeplay-0.3.24a0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|