freeplay 0.5.0a1__py3-none-any.whl → 0.5.0a3__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 -2
- freeplay/resources/recordings.py +4 -0
- freeplay/utils.py +42 -1
- {freeplay-0.5.0a1.dist-info → freeplay-0.5.0a3.dist-info}/METADATA +1 -1
- {freeplay-0.5.0a1.dist-info → freeplay-0.5.0a3.dist-info}/RECORD +8 -8
- {freeplay-0.5.0a1.dist-info → freeplay-0.5.0a3.dist-info}/LICENSE +0 -0
- {freeplay-0.5.0a1.dist-info → freeplay-0.5.0a3.dist-info}/WHEEL +0 -0
- {freeplay-0.5.0a1.dist-info → freeplay-0.5.0a3.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
|
|
@@ -185,6 +189,21 @@ class BoundPrompt:
|
|
185
189
|
for tool_schema in tool_schema
|
186
190
|
]
|
187
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()
|
188
207
|
|
189
208
|
raise UnsupportedToolSchemaError()
|
190
209
|
|
freeplay/resources/recordings.py
CHANGED
@@ -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
|
|
@@ -129,6 +130,9 @@ class Recordings:
|
|
129
130
|
if len(record_payload.all_messages) < 1:
|
130
131
|
raise FreeplayClientError("Messages list must have at least one message. "
|
131
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]
|
132
136
|
|
133
137
|
record_api_payload: Dict[str, Any] = {
|
134
138
|
"messages": record_payload.all_messages,
|
freeplay/utils.py
CHANGED
@@ -75,14 +75,55 @@ 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
|
-
|
78
|
+
"""
|
79
|
+
Convert provider message objects to dictionaries.
|
80
|
+
For Vertex AI objects, automatically converts to camelCase.
|
81
|
+
"""
|
82
|
+
# List of possible raw attribute names in Vertex AI objects
|
83
|
+
vertex_raw_attrs = [
|
84
|
+
'_raw_content', # For Content objects
|
85
|
+
'_raw_tool', # For Tool objects
|
86
|
+
'_raw_message', # For message objects
|
87
|
+
'_raw_candidate', # For Candidate objects
|
88
|
+
'_raw_response', # For response objects
|
89
|
+
'_raw_function_declaration', # For FunctionDeclaration
|
90
|
+
'_raw_generation_config', # For GenerationConfig
|
91
|
+
'_pb', # Generic protobuf attribute
|
92
|
+
]
|
93
|
+
|
94
|
+
# Check for Vertex AI objects with raw protobuf attributes
|
95
|
+
for attr_name in vertex_raw_attrs:
|
96
|
+
if hasattr(obj, attr_name):
|
97
|
+
raw_obj = getattr(obj, attr_name)
|
98
|
+
if raw_obj is not None:
|
99
|
+
try:
|
100
|
+
# Use the metaclass to_dict with camelCase conversion
|
101
|
+
return type(raw_obj).to_dict(
|
102
|
+
raw_obj,
|
103
|
+
preserving_proto_field_name=False, # camelCase
|
104
|
+
use_integers_for_enums=False, # Keep as strings (we'll lowercase them)
|
105
|
+
including_default_value_fields=False # Exclude defaults
|
106
|
+
)
|
107
|
+
except: # noqa: E722
|
108
|
+
# If we can't convert, continue to the next attribute
|
109
|
+
pass
|
110
|
+
|
111
|
+
# For non-Vertex AI objects, use their standard to_dict methods
|
112
|
+
if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')):
|
113
|
+
# Regular to_dict (for Vertex AI wrappers without _raw_* attributes)
|
114
|
+
return obj.to_dict()
|
115
|
+
elif hasattr(obj, 'model_dump'):
|
79
116
|
# Pydantic v2
|
80
117
|
return obj.model_dump(mode='json')
|
81
118
|
elif hasattr(obj, 'dict'):
|
82
119
|
# Pydantic v1
|
83
120
|
return obj.dict(encode_json=True)
|
84
121
|
elif isinstance(obj, dict):
|
122
|
+
# Handle dictionaries recursively
|
85
123
|
return {k: convert_provider_message_to_dict(v) for k, v in obj.items()}
|
86
124
|
elif isinstance(obj, list):
|
125
|
+
# Handle lists recursively
|
87
126
|
return [convert_provider_message_to_dict(item) for item in obj]
|
127
|
+
|
128
|
+
# Return as-is for primitive types
|
88
129
|
return obj
|
@@ -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.5.
|
20
|
-
freeplay-0.5.
|
21
|
-
freeplay-0.5.
|
22
|
-
freeplay-0.5.
|
23
|
-
freeplay-0.5.
|
18
|
+
freeplay/utils.py,sha256=OtoSnlDrLEk3MWiXmKFJ4Sw42-1kQ94-d_2ekHT6eUo,5038
|
19
|
+
freeplay-0.5.0a3.dist-info/LICENSE,sha256=_jzIw45hB1XHGxiQ8leZ0GH_X7bR_a8qgxaqnHbCUOo,1064
|
20
|
+
freeplay-0.5.0a3.dist-info/METADATA,sha256=wJZwNOsRV5Oq1xPG8Wbx1H4UpbC4oH6RbuVP_erRPqM,1662
|
21
|
+
freeplay-0.5.0a3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
22
|
+
freeplay-0.5.0a3.dist-info/entry_points.txt,sha256=32s3rf2UUCqiJT4jnClEXZhdXlvl30uwpcxz-Gsy4UU,54
|
23
|
+
freeplay-0.5.0a3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|