sunholo 0.84.8__py3-none-any.whl → 0.84.11__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.
@@ -59,6 +59,7 @@ class GenAIFunctionProcessor:
59
59
  self.config = config
60
60
  self.funcs = self.construct_tools()
61
61
  self.model_name = config.vacConfig("model") or "gemini-1.5-flash"
62
+ self.last_api_requests_and_responses = []
62
63
  self._validate_functions()
63
64
 
64
65
  def construct_tools(self) -> dict:
@@ -91,6 +92,84 @@ class GenAIFunctionProcessor:
91
92
  if not func.__doc__:
92
93
  log.error(f"Function {func_name} is missing a docstring.")
93
94
  raise ValueError(f"Function {func_name} must have a docstring to be used as a genai tool.")
95
+
96
+
97
+ def parse_as_parts(self, api_requests_and_responses=[]):
98
+ if not api_requests_and_responses and not self.last_api_requests_and_responses:
99
+ log.info("No api_requests_and_responses found to parse to parts")
100
+ return None
101
+
102
+ if api_requests_and_responses:
103
+ self.last_api_requests_and_responses = api_requests_and_responses
104
+
105
+ from google.generativeai.protos import Part
106
+
107
+ work_on = api_requests_and_responses or self.last_api_requests_and_responses
108
+ parts = []
109
+ for part in work_on:
110
+ parts.append(
111
+ Part(
112
+ function_response=genai.protos.FunctionResponse(
113
+ name=part[0],
114
+ response={"result": part[2]}
115
+ )
116
+ )
117
+ )
118
+
119
+ return parts
120
+
121
+ def check_function_result(self, function_name, target_value, api_requests_and_responses=[]):
122
+ """
123
+ Checks if a specific function result in the api_requests_and_responses contains a certain value.
124
+
125
+ Args:
126
+ function_name (str): The name of the function to check.
127
+ target_value: The value to look for in the function result.
128
+ api_requests_and_responses (list, optional): List of function call results to check.
129
+ If not provided, the method will use `self.last_api_requests_and_responses`.
130
+
131
+ Returns:
132
+ bool: True if the target_value is found in the specified function's result, otherwise False.
133
+ """
134
+ if not api_requests_and_responses:
135
+ api_requests_and_responses = self.last_api_requests_and_responses
136
+
137
+ if not api_requests_and_responses:
138
+ log.info("No api_requests_and_responses found to check.")
139
+ return False
140
+
141
+ for part in api_requests_and_responses:
142
+ func_name = part[0]
143
+ result = part[2]
144
+
145
+ if func_name == function_name:
146
+ if isinstance(result, list) and target_value in result:
147
+ log.info(f"Target value '{target_value}' found in the result of function '{function_name}'.")
148
+ return True
149
+ elif result == target_value:
150
+ log.info(f"Target value '{target_value}' found in the result of function '{function_name}'.")
151
+ return True
152
+
153
+ log.info(f"Target value '{target_value}' not found in the result of function '{function_name}'.")
154
+ return False
155
+
156
+ def parse_as_string(self, api_requests_and_responses=[]):
157
+ if not api_requests_and_responses and not self.last_api_requests_and_responses:
158
+ log.info("No api_requests_and_response found to parse to string")
159
+ return None
160
+
161
+ if api_requests_and_responses:
162
+ self.last_api_requests_and_responses = api_requests_and_responses
163
+
164
+ work_on = api_requests_and_responses or self.last_api_requests_and_responses
165
+ strings = []
166
+ for part in work_on:
167
+ strings.append(
168
+ f"function tool {part[0]} was called with arguments: {part[1]} and got this result:\n"
169
+ f"<{part[0]}_result>{part[2]}</{part[0]}_result>"
170
+ )
171
+
172
+ return strings
94
173
 
95
174
  def process_funcs(self, full_response, output_parts=True) -> Union[list['Part'], str]:
96
175
  """
@@ -112,8 +191,6 @@ class GenAIFunctionProcessor:
112
191
  results = alloydb_processor.process_funcs(full_response)
113
192
  ```
114
193
  """
115
- from google.generativeai.protos import Part
116
-
117
194
  api_requests_and_responses = []
118
195
 
119
196
  # Loop through each part in the response to handle multiple function calls
@@ -144,30 +221,33 @@ class GenAIFunctionProcessor:
144
221
  log.error(f"Function {function_name} is not recognized")
145
222
 
146
223
  log.info(f"{api_requests_and_responses=}")
224
+ self.last_api_requests_and_responses = api_requests_and_responses
147
225
 
148
226
  if output_parts:
149
- parts = []
150
- for part in api_requests_and_responses:
151
- parts.append(
152
- Part(
153
- function_response=genai.protos.FunctionResponse(
154
- name=part[0],
155
- response={"result": part[2]}
156
- )
157
- )
158
- )
159
- return parts
227
+ return self.parse_as_parts()
228
+
229
+ return self.parse_as_string()
230
+
231
+ def tool_config_setting(self, mode:str):
232
+ from google.generativeai.types import content_types
160
233
 
161
- strings = []
162
- for part in api_requests_and_responses:
163
- strings.append(
164
- f"function tool {part[0]} was called with arguments: {part[1]} and got this result:\n"
165
- f"<{part[0]}_result>{part[2]}</{part[0]}_result>"
166
- )
234
+ fns = list(self.funcs.keys())
167
235
 
168
- return strings
236
+ if fns and mode == "any":
237
+ return content_types.to_tool_config(
238
+ {"function_calling_config": {"mode": mode, "allowed_function_names": fns}}
239
+ )
240
+ else:
241
+ return content_types.to_tool_config(
242
+ {"function_calling_config": {"mode": mode}}
243
+ )
169
244
 
170
- def get_model(self, system_instruction: str, generation_config=None, model_name: str=None):
245
+ def get_model(
246
+ self,
247
+ system_instruction: str,
248
+ generation_config=None,
249
+ model_name: str=None,
250
+ tool_config: str="auto"):
171
251
  """
172
252
  Constructs and returns the generative AI model configured with the tools.
173
253
 
@@ -178,6 +258,7 @@ class GenAIFunctionProcessor:
178
258
  model_name (str): The name of the model to use.
179
259
  system_instruction (str): Instructions for the AI system.
180
260
  generation_config (dict, optional): Configuration for generation, such as temperature.
261
+ tool_config (str, optional): Configuration for tool behaviour: 'auto' it decides, 'none' no tools, 'any' always use tools
181
262
 
182
263
  Returns:
183
264
  GenerativeModel: An instance of the GenerativeModel configured with the provided tools.
@@ -204,6 +285,7 @@ class GenAIFunctionProcessor:
204
285
  model = genai.GenerativeModel(
205
286
  model_name=model_name or self.model_name,
206
287
  tools=tools,
288
+ tool_config=self.tool_config_setting(tool_config),
207
289
  generation_config=generation_config,
208
290
  safety_settings=genai_safety(),
209
291
  system_instruction=system_instruction,
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.84.8
3
+ Version: 0.84.11
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.84.8.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.84.11.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -83,7 +83,7 @@ sunholo/gcs/download_folder.py,sha256=ijJTnS595JqZhBH8iHFErQilMbkuKgL-bnTCMLGuvl
83
83
  sunholo/gcs/download_url.py,sha256=q1NiJSvEhdNrmU5ZJ-sBCMC_J5CxzrajY8LRgdPOV_M,6130
84
84
  sunholo/gcs/metadata.py,sha256=oQLcXi4brsZ74aegWyC1JZmhlaEV270HS5_UWtAYYWE,898
85
85
  sunholo/genai/__init__.py,sha256=o2c17UbgzIDxNKKF8deCLoctNpatAYgm9Cf9XDfpqvg,87
86
- sunholo/genai/process_funcs_cls.py,sha256=q0XbsLaMWhN7LCukRGaXr0KzJtGmxbu6OVoGd3o3ibM,8270
86
+ sunholo/genai/process_funcs_cls.py,sha256=xnSxGGEHO7fYct8VkjaOKSBmHG-cEkvFTZqFLsN_oCc,11798
87
87
  sunholo/genai/safety.py,sha256=mkFDO_BeEgiKjQd9o2I4UxB6XI7a9U-oOFjZ8LGRUC4,1238
88
88
  sunholo/invoke/__init__.py,sha256=bELcqIjzKvaupcIN5OQmDgGx_8jARtH9T6PCe8UgcvE,99
89
89
  sunholo/invoke/async_class.py,sha256=J-qMgarhdi6nPQyOIFM5k0wF7nqr8aJGaz99-Ye6XGQ,3507
@@ -138,9 +138,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
138
138
  sunholo/vertex/memory_tools.py,sha256=q_phxgGX2TG2j2MXNULF2xGzQnQPENwjPN9nZ_A9Gh0,7526
139
139
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
140
140
  sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
141
- sunholo-0.84.8.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
142
- sunholo-0.84.8.dist-info/METADATA,sha256=iEv_hxCGy1Jyw1icFKKEStYm01YhOBKTtTUMk8HrWIQ,7412
143
- sunholo-0.84.8.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
144
- sunholo-0.84.8.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
145
- sunholo-0.84.8.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
146
- sunholo-0.84.8.dist-info/RECORD,,
141
+ sunholo-0.84.11.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
142
+ sunholo-0.84.11.dist-info/METADATA,sha256=RvW8QNW0Wr4RzLiPFpT3tmBHbF44W-wohn2jrsGgxYs,7414
143
+ sunholo-0.84.11.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
144
+ sunholo-0.84.11.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
145
+ sunholo-0.84.11.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
146
+ sunholo-0.84.11.dist-info/RECORD,,