freeplay 0.4.1__py3-none-any.whl → 0.5.0a2__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/resources/prompts.py +21 -6
- freeplay/resources/recordings.py +30 -20
- freeplay/utils.py +4 -1
- {freeplay-0.4.1.dist-info → freeplay-0.5.0a2.dist-info}/METADATA +1 -1
- {freeplay-0.4.1.dist-info → freeplay-0.5.0a2.dist-info}/RECORD +8 -8
- {freeplay-0.4.1.dist-info → freeplay-0.5.0a2.dist-info}/WHEEL +1 -1
- {freeplay-0.4.1.dist-info → freeplay-0.5.0a2.dist-info}/LICENSE +0 -0
- {freeplay-0.4.1.dist-info → freeplay-0.5.0a2.dist-info}/entry_points.txt +0 -0
freeplay/resources/prompts.py
CHANGED
@@ -8,7 +8,6 @@ from typing import (
|
|
8
8
|
Any,
|
9
9
|
Dict,
|
10
10
|
List,
|
11
|
-
Literal,
|
12
11
|
Optional,
|
13
12
|
Protocol,
|
14
13
|
Sequence,
|
@@ -56,7 +55,12 @@ logger = logging.getLogger(__name__)
|
|
56
55
|
class UnsupportedToolSchemaError(FreeplayConfigurationError):
|
57
56
|
def __init__(self) -> None:
|
58
57
|
super().__init__(
|
59
|
-
|
58
|
+
'Tool schema not supported for this model and provider.'
|
59
|
+
)
|
60
|
+
class VertexAIToolSchemaError(FreeplayConfigurationError):
|
61
|
+
def __init__(self) -> None:
|
62
|
+
super().__init__(
|
63
|
+
'Vertex AI SDK not found. Install google-cloud-aiplatform to get proper Tool objects.'
|
60
64
|
)
|
61
65
|
|
62
66
|
|
@@ -100,8 +104,6 @@ class PromptInfo:
|
|
100
104
|
provider: str
|
101
105
|
model: str
|
102
106
|
flavor_name: str
|
103
|
-
project_id: str
|
104
|
-
|
105
107
|
|
106
108
|
class FormattedPrompt:
|
107
109
|
def __init__(
|
@@ -187,6 +189,21 @@ class BoundPrompt:
|
|
187
189
|
for tool_schema in tool_schema
|
188
190
|
]
|
189
191
|
}
|
192
|
+
elif flavor_name == "gemini_chat":
|
193
|
+
try:
|
194
|
+
from vertexai.generative_models import Tool, FunctionDeclaration # type: ignore[import-untyped]
|
195
|
+
|
196
|
+
function_declarations = [
|
197
|
+
FunctionDeclaration(
|
198
|
+
name=tool_schema.name,
|
199
|
+
description=tool_schema.description,
|
200
|
+
parameters=tool_schema.parameters
|
201
|
+
)
|
202
|
+
for tool_schema in tool_schema
|
203
|
+
]
|
204
|
+
return [Tool(function_declarations=function_declarations)]
|
205
|
+
except ImportError:
|
206
|
+
raise VertexAIToolSchemaError()
|
190
207
|
|
191
208
|
raise UnsupportedToolSchemaError()
|
192
209
|
|
@@ -540,7 +557,6 @@ class Prompts:
|
|
540
557
|
model=model,
|
541
558
|
flavor_name=prompt.metadata.flavor,
|
542
559
|
provider_info=prompt.metadata.provider_info,
|
543
|
-
project_id=prompt.project_id
|
544
560
|
)
|
545
561
|
|
546
562
|
return TemplatePrompt(prompt_info, prompt.content, prompt.tool_schema)
|
@@ -576,7 +592,6 @@ class Prompts:
|
|
576
592
|
model=model,
|
577
593
|
flavor_name=prompt.metadata.flavor,
|
578
594
|
provider_info=prompt.metadata.provider_info,
|
579
|
-
project_id=prompt.project_id
|
580
595
|
)
|
581
596
|
|
582
597
|
return TemplatePrompt(prompt_info, prompt.content, prompt.tool_schema)
|
freeplay/resources/recordings.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import json
|
2
2
|
import logging
|
3
|
-
from dataclasses import dataclass
|
3
|
+
from dataclasses import dataclass, field
|
4
4
|
from typing import Any, Dict, List, Literal, Optional, Union
|
5
|
-
from uuid import UUID
|
5
|
+
from uuid import UUID, uuid4
|
6
6
|
|
7
7
|
from requests import HTTPError
|
8
8
|
|
@@ -22,6 +22,7 @@ from freeplay.resources.prompts import (
|
|
22
22
|
)
|
23
23
|
from freeplay.resources.sessions import SessionInfo, TraceInfo
|
24
24
|
from freeplay.support import CallSupport
|
25
|
+
from freeplay.utils import convert_provider_message_to_dict
|
25
26
|
|
26
27
|
logger = logging.getLogger(__name__)
|
27
28
|
|
@@ -37,11 +38,11 @@ ApiStyle = Union[Literal['batch'], Literal['default']]
|
|
37
38
|
|
38
39
|
@dataclass
|
39
40
|
class CallInfo:
|
40
|
-
provider: str
|
41
|
-
model: str
|
42
|
-
start_time: float
|
43
|
-
end_time: float
|
44
|
-
model_parameters: LLMParameters
|
41
|
+
provider: Optional[str] = None
|
42
|
+
model: Optional[str] = None
|
43
|
+
start_time: Optional[float] = None
|
44
|
+
end_time: Optional[float] = None
|
45
|
+
model_parameters: Optional[LLMParameters] = None
|
45
46
|
provider_info: Optional[Dict[str, Any]] = None
|
46
47
|
usage: Optional[UsageTokens] = None
|
47
48
|
api_style: Optional[ApiStyle] = None
|
@@ -77,12 +78,15 @@ class ResponseInfo:
|
|
77
78
|
|
78
79
|
@dataclass
|
79
80
|
class RecordPayload:
|
81
|
+
project_id: str
|
80
82
|
all_messages: List[Dict[str, Any]]
|
81
|
-
inputs: InputVariables
|
82
83
|
|
83
|
-
session_info: SessionInfo
|
84
|
-
|
85
|
-
|
84
|
+
session_info: SessionInfo = field(
|
85
|
+
default_factory=lambda: SessionInfo(session_id=str(uuid4()), custom_metadata=None)
|
86
|
+
)
|
87
|
+
inputs: Optional[InputVariables] = None
|
88
|
+
prompt_info: Optional[PromptInfo] = None
|
89
|
+
call_info: Optional[CallInfo] = None
|
86
90
|
media_inputs: Optional[MediaInputMap] = None
|
87
91
|
tool_schema: Optional[List[Dict[str, Any]]] = None
|
88
92
|
response_info: Optional[ResponseInfo] = None
|
@@ -126,25 +130,34 @@ class Recordings:
|
|
126
130
|
if len(record_payload.all_messages) < 1:
|
127
131
|
raise FreeplayClientError("Messages list must have at least one message. "
|
128
132
|
"The last message should be the current response.")
|
133
|
+
|
134
|
+
if record_payload.tool_schema is not None:
|
135
|
+
record_payload.tool_schema = [convert_provider_message_to_dict(tool) for tool in record_payload.tool_schema]
|
129
136
|
|
130
137
|
record_api_payload: Dict[str, Any] = {
|
131
138
|
"messages": record_payload.all_messages,
|
132
139
|
"inputs": record_payload.inputs,
|
133
140
|
"tool_schema": record_payload.tool_schema,
|
134
141
|
"session_info": {"custom_metadata": record_payload.session_info.custom_metadata},
|
135
|
-
|
142
|
+
|
143
|
+
}
|
144
|
+
|
145
|
+
if record_payload.prompt_info is not None:
|
146
|
+
record_api_payload["prompt_info"] = {
|
136
147
|
"environment": record_payload.prompt_info.environment,
|
137
148
|
"prompt_template_version_id": record_payload.prompt_info.prompt_template_version_id,
|
138
|
-
}
|
139
|
-
|
149
|
+
}
|
150
|
+
|
151
|
+
if record_payload.call_info is not None:
|
152
|
+
record_api_payload["call_info"] = {
|
140
153
|
"start_time": record_payload.call_info.start_time,
|
141
154
|
"end_time": record_payload.call_info.end_time,
|
142
155
|
"model": record_payload.call_info.model,
|
143
156
|
"provider": record_payload.call_info.provider,
|
144
157
|
"provider_info": record_payload.call_info.provider_info,
|
145
158
|
"llm_parameters": record_payload.call_info.model_parameters,
|
159
|
+
"api_style": record_payload.call_info.api_style,
|
146
160
|
}
|
147
|
-
}
|
148
161
|
|
149
162
|
if record_payload.completion_id is not None:
|
150
163
|
record_api_payload['completion_id'] = str(record_payload.completion_id)
|
@@ -175,15 +188,12 @@ class Recordings:
|
|
175
188
|
"trace_id": record_payload.trace_info.trace_id
|
176
189
|
}
|
177
190
|
|
178
|
-
if record_payload.call_info.usage is not None:
|
191
|
+
if record_payload.call_info is not None and record_payload.call_info.usage is not None:
|
179
192
|
record_api_payload['call_info']['usage'] = {
|
180
193
|
"prompt_tokens": record_payload.call_info.usage.prompt_tokens,
|
181
194
|
"completion_tokens": record_payload.call_info.usage.completion_tokens,
|
182
195
|
}
|
183
196
|
|
184
|
-
if record_payload.call_info.api_style is not None:
|
185
|
-
record_api_payload['call_info']['api_style'] = record_payload.call_info.api_style
|
186
|
-
|
187
197
|
if record_payload.media_inputs is not None:
|
188
198
|
record_api_payload['media_inputs'] = {
|
189
199
|
name: media_inputs_to_json(media_input)
|
@@ -193,7 +203,7 @@ class Recordings:
|
|
193
203
|
try:
|
194
204
|
recorded_response = api_support.post_raw(
|
195
205
|
api_key=self.call_support.freeplay_api_key,
|
196
|
-
url=f'{self.call_support.api_base}/v2/projects/{record_payload.
|
206
|
+
url=f'{self.call_support.api_base}/v2/projects/{record_payload.project_id}/sessions/{record_payload.session_info.session_id}/completions',
|
197
207
|
payload=record_api_payload
|
198
208
|
)
|
199
209
|
recorded_response.raise_for_status()
|
freeplay/utils.py
CHANGED
@@ -75,7 +75,10 @@ def get_user_agent() -> str:
|
|
75
75
|
# Recursively convert Pydantic models, lists, and dicts to dict compatible format -- used to allow us to accept
|
76
76
|
# provider message shapes (usually generated types) or the default {'content': ..., 'role': ...} shape.
|
77
77
|
def convert_provider_message_to_dict(obj: Any) -> Any:
|
78
|
-
if hasattr(obj, '
|
78
|
+
if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')):
|
79
|
+
# Vertex AI has a to_dict method
|
80
|
+
return obj.to_dict()
|
81
|
+
elif hasattr(obj, 'model_dump'):
|
79
82
|
# Pydantic v2
|
80
83
|
return obj.model_dump(mode='json')
|
81
84
|
elif hasattr(obj, 'dict'):
|
@@ -9,15 +9,15 @@ 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=6AUgHyOcXIpHvrxGAhsQgmDERvRHKutB6J-GkhkGH6s,928
|
12
|
-
freeplay/resources/prompts.py,sha256=
|
13
|
-
freeplay/resources/recordings.py,sha256=
|
12
|
+
freeplay/resources/prompts.py,sha256=pkZa_b3HSrZoPqhcKCXsb26w2In-ETKydclbkXU_hus,24093
|
13
|
+
freeplay/resources/recordings.py,sha256=OOSgSkQO7CVnOA2y7eSl5B2eMHZv5E3_-3J2XILwKUo,9811
|
14
14
|
freeplay/resources/sessions.py,sha256=dZtd9nq2nH8pmXxQOJitBnN5Jl3kjggDItDcjC69TYo,3883
|
15
15
|
freeplay/resources/test_cases.py,sha256=nXL_976RwSJDT6OWDM4GEzbcOzcGkJ9ulvb0XOzCRDM,2240
|
16
16
|
freeplay/resources/test_runs.py,sha256=IkqW2LrVrLzFcGtalwP4FV-DeQKKb6Nekvy02FfoH8k,5007
|
17
17
|
freeplay/support.py,sha256=9X-utKyM9BkhCLJbPT184ud26Dc69f3DiHjyN8qq0vQ,15266
|
18
|
-
freeplay/utils.py,sha256=
|
19
|
-
freeplay-0.
|
20
|
-
freeplay-0.
|
21
|
-
freeplay-0.
|
22
|
-
freeplay-0.
|
23
|
-
freeplay-0.
|
18
|
+
freeplay/utils.py,sha256=5mNC3NTHDlzltyUDF8q2wNddgGy6-MhI8ldnRvtAl7U,3329
|
19
|
+
freeplay-0.5.0a2.dist-info/LICENSE,sha256=_jzIw45hB1XHGxiQ8leZ0GH_X7bR_a8qgxaqnHbCUOo,1064
|
20
|
+
freeplay-0.5.0a2.dist-info/METADATA,sha256=pzFZ1UFoEM-rCaL11UHjH_pMjYg20tRGog0zptc5cnQ,1662
|
21
|
+
freeplay-0.5.0a2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
22
|
+
freeplay-0.5.0a2.dist-info/entry_points.txt,sha256=32s3rf2UUCqiJT4jnClEXZhdXlvl30uwpcxz-Gsy4UU,54
|
23
|
+
freeplay-0.5.0a2.dist-info/RECORD,,
|
File without changes
|
File without changes
|