freeplay 0.3.21__tar.gz → 0.3.23__tar.gz

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.
Files changed (22) hide show
  1. {freeplay-0.3.21 → freeplay-0.3.23}/PKG-INFO +1 -1
  2. {freeplay-0.3.21 → freeplay-0.3.23}/pyproject.toml +1 -1
  3. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/adapters.py +26 -2
  4. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/prompts.py +27 -6
  5. {freeplay-0.3.21 → freeplay-0.3.23}/LICENSE +0 -0
  6. {freeplay-0.3.21 → freeplay-0.3.23}/README.md +0 -0
  7. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/__init__.py +0 -0
  8. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/api_support.py +0 -0
  9. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/errors.py +0 -0
  10. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/freeplay.py +0 -0
  11. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/freeplay_cli.py +0 -0
  12. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/llm_parameters.py +0 -0
  13. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/model.py +0 -0
  14. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/py.typed +0 -0
  15. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/__init__.py +0 -0
  16. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/customer_feedback.py +0 -0
  17. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/recordings.py +0 -0
  18. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/sessions.py +0 -0
  19. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/test_cases.py +0 -0
  20. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/resources/test_runs.py +0 -0
  21. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/support.py +0 -0
  22. {freeplay-0.3.21 → freeplay-0.3.23}/src/freeplay/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: freeplay
3
- Version: 0.3.21
3
+ Version: 0.3.23
4
4
  Summary:
5
5
  License: MIT
6
6
  Author: FreePlay Engineering
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "freeplay"
3
- version = "0.3.21"
3
+ version = "0.3.23"
4
4
  description = ""
5
5
  authors = ["FreePlay Engineering <engineering@freeplay.ai>"]
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  import copy
2
2
  from dataclasses import dataclass
3
- from typing import Protocol, Dict, List, Union, Any
3
+ from typing import Any, Dict, List, Protocol, Union
4
4
 
5
5
  from freeplay.errors import FreeplayConfigurationError
6
6
  from freeplay.support import MediaType
@@ -35,6 +35,7 @@ class MissingFlavorError(FreeplayConfigurationError):
35
35
 
36
36
 
37
37
  class LLMAdapter(Protocol):
38
+ # This method must handle BOTH prompt template messages and provider specific messages.
38
39
  def to_llm_syntax(self, messages: List[Dict[str, Any]]) -> Union[str, List[Dict[str, Any]]]:
39
40
  pass
40
41
 
@@ -187,11 +188,13 @@ class GeminiAdapter(LLMAdapter):
187
188
  "role": self.__translate_role(message["role"]),
188
189
  "parts": [self.__map_content(content) for content in message['content']]
189
190
  })
190
- else:
191
+ elif "content" in message:
191
192
  gemini_messages.append({
192
193
  "role": self.__translate_role(message["role"]),
193
194
  "parts": [{"text": message["content"]}]
194
195
  })
196
+ else:
197
+ gemini_messages.append(copy.deepcopy(message))
195
198
 
196
199
  return gemini_messages
197
200
 
@@ -221,6 +224,25 @@ class GeminiAdapter(LLMAdapter):
221
224
  raise ValueError(f"Gemini formatting found unexpected role {role}")
222
225
 
223
226
 
227
+ class BedrockConverseAdapter(LLMAdapter):
228
+ def to_llm_syntax(self, messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
229
+ converse_messages = []
230
+ for message in messages:
231
+ if message["role"] == "system":
232
+ continue
233
+ if "has_media" in message and message["has_media"]:
234
+ raise ValueError("Bedrock Converse does not support media content yet")
235
+
236
+ role = message["role"]
237
+ content = message["content"]
238
+ if role not in ["user", "assistant"]:
239
+ raise ValueError(f"Unexpected role for Bedrock Converse flavor: {role}")
240
+ if isinstance(content, str):
241
+ content = [{"text": content}]
242
+ converse_messages.append({"role": role, "content": content})
243
+ return converse_messages
244
+
245
+
224
246
  def adaptor_for_flavor(flavor_name: str) -> LLMAdapter:
225
247
  if flavor_name in ["baseten_mistral_chat", "mistral_chat", "perplexity_chat"]:
226
248
  return PassthroughAdapter()
@@ -232,5 +254,7 @@ def adaptor_for_flavor(flavor_name: str) -> LLMAdapter:
232
254
  return Llama3Adapter()
233
255
  elif flavor_name == "gemini_chat":
234
256
  return GeminiAdapter()
257
+ elif flavor_name == "amazon_bedrock_converse":
258
+ return BedrockConverseAdapter()
235
259
  else:
236
260
  raise MissingFlavorError(flavor_name)
@@ -8,6 +8,7 @@ from typing import (
8
8
  Any,
9
9
  Dict,
10
10
  List,
11
+ Literal,
11
12
  Optional,
12
13
  Protocol,
13
14
  Sequence,
@@ -15,7 +16,6 @@ from typing import (
15
16
  Union,
16
17
  cast,
17
18
  runtime_checkable,
18
- Literal,
19
19
  )
20
20
 
21
21
  from freeplay.errors import (
@@ -25,15 +25,24 @@ from freeplay.errors import (
25
25
  )
26
26
  from freeplay.llm_parameters import LLMParameters
27
27
  from freeplay.model import InputVariables
28
- from freeplay.resources.adapters import MissingFlavorError, adaptor_for_flavor, MediaContentBase64, MediaContentUrl, \
29
- TextContent
28
+ from freeplay.resources.adapters import (
29
+ MediaContentBase64,
30
+ MediaContentUrl,
31
+ MissingFlavorError,
32
+ TextContent,
33
+ adaptor_for_flavor,
34
+ )
30
35
  from freeplay.support import (
31
36
  CallSupport,
37
+ HistoryTemplateMessage,
38
+ MediaSlot,
32
39
  PromptTemplate,
33
40
  PromptTemplateMetadata,
34
41
  PromptTemplates,
42
+ Role,
43
+ TemplateChatMessage,
35
44
  TemplateMessage,
36
- ToolSchema, TemplateChatMessage, HistoryTemplateMessage, MediaSlot, Role,
45
+ ToolSchema,
37
46
  )
38
47
  from freeplay.utils import bind_template_variables, convert_provider_message_to_dict
39
48
 
@@ -147,7 +156,7 @@ class BoundPrompt:
147
156
  self.tool_schema = tool_schema
148
157
 
149
158
  @staticmethod
150
- def __format_tool_schema(flavor_name: str, tool_schema: List[ToolSchema]) -> List[Dict[str, Any]]:
159
+ def __format_tool_schema(flavor_name: str, tool_schema: List[ToolSchema]) -> Any:
151
160
  if flavor_name == 'anthropic_chat':
152
161
  return [{
153
162
  'name': tool_schema.name,
@@ -161,6 +170,19 @@ class BoundPrompt:
161
170
  'type': 'function'
162
171
  } for tool_schema in tool_schema
163
172
  ]
173
+ elif flavor_name == "amazon_bedrock_converse":
174
+ return {
175
+ "tools": [
176
+ {
177
+ "toolSpec": {
178
+ "name": tool_schema.name,
179
+ "description": tool_schema.description,
180
+ "inputSchema": {"json": tool_schema.parameters},
181
+ }
182
+ }
183
+ for tool_schema in tool_schema
184
+ ]
185
+ }
164
186
 
165
187
  raise UnsupportedToolSchemaError()
166
188
 
@@ -171,7 +193,6 @@ class BoundPrompt:
171
193
  final_flavor = flavor_name or self.prompt_info.flavor_name
172
194
  adapter = adaptor_for_flavor(final_flavor)
173
195
  formatted_prompt = adapter.to_llm_syntax(self.messages)
174
-
175
196
  formatted_tool_schema = BoundPrompt.__format_tool_schema(
176
197
  final_flavor,
177
198
  self.tool_schema
File without changes
File without changes