sunholo 0.74.9__py3-none-any.whl → 0.75.1__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.
- sunholo/auth/__init__.py +1 -0
- sunholo/auth/gcloud.py +14 -0
- sunholo/auth/run.py +4 -12
- sunholo/tools/web_browser.py +66 -0
- sunholo/vertex/extensions_class.py +24 -1
- {sunholo-0.74.9.dist-info → sunholo-0.75.1.dist-info}/METADATA +2 -2
- {sunholo-0.74.9.dist-info → sunholo-0.75.1.dist-info}/RECORD +11 -10
- {sunholo-0.74.9.dist-info → sunholo-0.75.1.dist-info}/WHEEL +1 -1
- {sunholo-0.74.9.dist-info → sunholo-0.75.1.dist-info}/LICENSE.txt +0 -0
- {sunholo-0.74.9.dist-info → sunholo-0.75.1.dist-info}/entry_points.txt +0 -0
- {sunholo-0.74.9.dist-info → sunholo-0.75.1.dist-info}/top_level.txt +0 -0
sunholo/auth/__init__.py
CHANGED
sunholo/auth/gcloud.py
ADDED
sunholo/auth/run.py
CHANGED
|
@@ -7,6 +7,7 @@ from ..utils.gcp import is_running_on_cloudrun
|
|
|
7
7
|
from ..utils.api_key import has_multivac_api_key, get_multivac_api_key
|
|
8
8
|
from ..logging import log
|
|
9
9
|
from ..agents.route import route_vac
|
|
10
|
+
from .gcloud import get_local_gcloud_token
|
|
10
11
|
|
|
11
12
|
def get_run_url(vector_name=None):
|
|
12
13
|
|
|
@@ -33,20 +34,11 @@ def get_id_token(url: str) -> str:
|
|
|
33
34
|
import google.oauth2.id_token # type: ignore
|
|
34
35
|
auth_req = google.auth.transport.requests.Request()
|
|
35
36
|
log.info(f'Got id_token for {url}')
|
|
37
|
+
|
|
36
38
|
return google.oauth2.id_token.fetch_id_token(auth_req, url)
|
|
37
|
-
else:
|
|
38
|
-
# Use gcloud credentials locally
|
|
39
|
-
import subprocess
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
["gcloud", "auth", "print-identity-token"],
|
|
44
|
-
stdout=subprocess.PIPE,
|
|
45
|
-
check=True,
|
|
46
|
-
)
|
|
47
|
-
.stdout.strip()
|
|
48
|
-
.decode()
|
|
49
|
-
)
|
|
40
|
+
return get_local_gcloud_token()
|
|
41
|
+
|
|
50
42
|
|
|
51
43
|
def get_header(vector_name) -> Optional[dict]:
|
|
52
44
|
if has_multivac_api_key():
|
sunholo/tools/web_browser.py
CHANGED
|
@@ -361,6 +361,68 @@ class BrowseWebWithImagePromptsBot:
|
|
|
361
361
|
|
|
362
362
|
return (x, y)
|
|
363
363
|
|
|
364
|
+
def execute_custom_command(self, command):
|
|
365
|
+
"""
|
|
366
|
+
Executes a custom command on the page object.
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
command (str): The command string to be executed.
|
|
370
|
+
"""
|
|
371
|
+
try:
|
|
372
|
+
element_part = command.get('get_locator')
|
|
373
|
+
operation = command.get('operation')
|
|
374
|
+
|
|
375
|
+
if not element_part or not operation:
|
|
376
|
+
raise ValueError("Both 'element_part' and 'operation' must be provided in the command")
|
|
377
|
+
|
|
378
|
+
# Dynamically get the method and its parameters
|
|
379
|
+
method_name, params = self.parse_element_part(element_part)
|
|
380
|
+
method = getattr(self.page, method_name)
|
|
381
|
+
element = method(*params)
|
|
382
|
+
|
|
383
|
+
if not element:
|
|
384
|
+
raise ValueError(f"Element not found for selector: {element_part}")
|
|
385
|
+
|
|
386
|
+
# Execute the operation
|
|
387
|
+
exec(f"element.{operation}")
|
|
388
|
+
|
|
389
|
+
# Mark the action on the screenshot
|
|
390
|
+
bounding_box = element.bounding_box()
|
|
391
|
+
if bounding_box:
|
|
392
|
+
x = bounding_box['x'] + bounding_box['width'] / 2
|
|
393
|
+
y = bounding_box['y'] + bounding_box['height'] / 2
|
|
394
|
+
mark_action = {'type': operation, 'position': (x, y)}
|
|
395
|
+
self.take_screenshot(mark_action=mark_action)
|
|
396
|
+
else:
|
|
397
|
+
self.take_screenshot()
|
|
398
|
+
|
|
399
|
+
log.info(f"Executed custom command on element: {element_part} with operation: {operation}")
|
|
400
|
+
self.action_log.append(f"Executed custom command on element: {element_part} with operation: {operation}")
|
|
401
|
+
|
|
402
|
+
except Exception as e:
|
|
403
|
+
log.error(f"Failed to execute custom command: {command}. Error: {str(e)}")
|
|
404
|
+
self.action_log.append(f"Failed to execute custom command: {command}. Error: {str(e)}")
|
|
405
|
+
|
|
406
|
+
def parse_element_part(self, element_part):
|
|
407
|
+
"""
|
|
408
|
+
Parses the element_part string to extract the method name and its parameters.
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
element_part (str): The element part string (e.g., "get_by_role('button')")
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
tuple: A tuple containing the method name and a list of parameters.
|
|
415
|
+
"""
|
|
416
|
+
try:
|
|
417
|
+
# Extract the method name and parameters
|
|
418
|
+
method_name = element_part.split('(')[0]
|
|
419
|
+
params_str = element_part.split('(')[1].rstrip(')')
|
|
420
|
+
params = eval(f'[{params_str}]') # Safely evaluate parameters
|
|
421
|
+
|
|
422
|
+
return method_name, params
|
|
423
|
+
except Exception as e:
|
|
424
|
+
raise ValueError(f"Failed to parse element part: {element_part}. Error: {str(e)}")
|
|
425
|
+
|
|
364
426
|
def take_screenshot(self, full_page=False, mark_action=None):
|
|
365
427
|
|
|
366
428
|
from PIL import Image
|
|
@@ -523,6 +585,10 @@ This method should be implemented by subclasses: `def send_prompt_to_llm(self, p
|
|
|
523
585
|
x,y = self.type_text(instruction['selector'], instruction['text'])
|
|
524
586
|
if (x,y) != (0,0):
|
|
525
587
|
mark_action = {'type':'type', 'position': (x,y)}
|
|
588
|
+
elif action == 'execute':
|
|
589
|
+
x,y,mark = self.execute_custom_command(instruction['command'])
|
|
590
|
+
if mark:
|
|
591
|
+
mark_action = {'type': mark, 'position': (x,y)}
|
|
526
592
|
self.steps += 1
|
|
527
593
|
if self.steps >= self.max_steps:
|
|
528
594
|
log.warning(f"Reached the maximum number of steps: {self.max_steps}")
|
|
@@ -88,7 +88,7 @@ class VertexAIExtensions:
|
|
|
88
88
|
from openapi_spec_validator import validate
|
|
89
89
|
from openapi_spec_validator.readers import read_from_filename
|
|
90
90
|
except ImportError:
|
|
91
|
-
raise ImportError("Must have openapi-spec-validator installed - install via `pip install sunholo[tools]`")
|
|
91
|
+
raise ImportError("Must have openapi-spec-validator installed - install via `pip install sunholo'[tools]'`")
|
|
92
92
|
|
|
93
93
|
spec_dict, spec_url = read_from_filename(filename)
|
|
94
94
|
validate(spec_dict)
|
|
@@ -198,6 +198,11 @@ class VertexAIExtensions:
|
|
|
198
198
|
project_id = get_gcp_project()
|
|
199
199
|
extension_name = f"projects/{project_id}/locations/us-central1/extensions/{validate_extension_id(display_name)}"
|
|
200
200
|
|
|
201
|
+
listed_extensions = self.list_extensions()
|
|
202
|
+
for ext in listed_extensions:
|
|
203
|
+
if ext.get('resource_name') == extension_name:
|
|
204
|
+
raise NameError(f"resouce_name {extension_name} already exists. Delete it or rename your new extension")
|
|
205
|
+
|
|
201
206
|
if open_api_file:
|
|
202
207
|
self.upload_openapi_file(open_api_file)
|
|
203
208
|
|
|
@@ -236,6 +241,7 @@ class VertexAIExtensions:
|
|
|
236
241
|
if extension_name is None:
|
|
237
242
|
raise ValueError("Must specify extension_id or init one with class")
|
|
238
243
|
else:
|
|
244
|
+
extension_id = str(extension_id)
|
|
239
245
|
if not extension_id.startswith("projects/"):
|
|
240
246
|
project_id = get_gcp_project()
|
|
241
247
|
extension_name = f"projects/{project_id}/locations/{self.location}/extensions/{extension_id}"
|
|
@@ -244,11 +250,28 @@ class VertexAIExtensions:
|
|
|
244
250
|
|
|
245
251
|
extension = extensions.Extension(extension_name)
|
|
246
252
|
|
|
253
|
+
log.info(f"Executing extension {extension_name=} with {operation_id=} and {operation_params=}")
|
|
254
|
+
|
|
255
|
+
# local testing auth
|
|
256
|
+
from ..utils.gcp import is_running_on_cloudrun
|
|
257
|
+
auth_config=None # on cloud run it sorts itself out via default creds(?)
|
|
258
|
+
|
|
259
|
+
if not is_running_on_cloudrun():
|
|
260
|
+
from ..auth import get_local_gcloud_token
|
|
261
|
+
log.warning("Using local authentication via gcloud")
|
|
262
|
+
auth_config = {
|
|
263
|
+
"authType": "OAUTH",
|
|
264
|
+
"oauth_config": {"access_token": f"'{get_local_gcloud_token()}'"}
|
|
265
|
+
}
|
|
266
|
+
|
|
247
267
|
response = extension.execute(
|
|
248
268
|
operation_id=operation_id,
|
|
249
269
|
operation_params=operation_params,
|
|
270
|
+
runtime_auth_config=auth_config
|
|
250
271
|
)
|
|
251
272
|
|
|
273
|
+
log.info(f"Extension {extension_name=} {response=}")
|
|
274
|
+
|
|
252
275
|
return response
|
|
253
276
|
|
|
254
277
|
def execute_code_extension(self,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.75.1
|
|
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.
|
|
6
|
+
Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.75.1.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -17,8 +17,9 @@ sunholo/agents/flask/qna_routes.py,sha256=nY0NFgezxw1pEGUq49AIJ5nqIx4lLcUJAMD_FE
|
|
|
17
17
|
sunholo/agents/flask/vac_routes.py,sha256=l2-w7x437F0Uu3QvwNueEYPtnKuIee6bHJ7LUMt_tkY,19520
|
|
18
18
|
sunholo/archive/__init__.py,sha256=qNHWm5rGPVOlxZBZCpA1wTYPbalizRT7f8X4rs2t290,31
|
|
19
19
|
sunholo/archive/archive.py,sha256=C-UhG5x-XtZ8VheQp92IYJqgD0V3NFQjniqlit94t18,1197
|
|
20
|
-
sunholo/auth/__init__.py,sha256=
|
|
21
|
-
sunholo/auth/
|
|
20
|
+
sunholo/auth/__init__.py,sha256=Y4Wpd6m0d3R7U7Ser51drO0Eg7VrfSS2VphZxRgtih8,70
|
|
21
|
+
sunholo/auth/gcloud.py,sha256=PdbwkuTdRi4RKBmgG9uwsReegqC4VG15_tw5uzmA7Fs,298
|
|
22
|
+
sunholo/auth/run.py,sha256=SG53ToQJ8hyjdN4634osfvDEUv5gJU6dlHe4nGwMMYU,2612
|
|
22
23
|
sunholo/bots/__init__.py,sha256=EMFd7e2z68l6pzYOnkzHbLd2xJRvxTKFRNCTuhZ8hIw,130
|
|
23
24
|
sunholo/bots/discord.py,sha256=cCFae5K1BCa6JVkWGLh_iZ9qFO1JpXb6K4eJrlDfEro,2442
|
|
24
25
|
sunholo/bots/github_webhook.py,sha256=5pQPRLM_wxxcILVaIzUDV8Kt7Arcm2dL1r1kMMHA524,9629
|
|
@@ -99,7 +100,7 @@ sunholo/streaming/streaming.py,sha256=9z6pXINEopuL_Z1RnmgXAoZJum9dzyuOxqYtEYnjf8
|
|
|
99
100
|
sunholo/summarise/__init__.py,sha256=MZk3dblUMODcPb1crq4v-Z508NrFIpkSWNf9FIO8BcU,38
|
|
100
101
|
sunholo/summarise/summarise.py,sha256=C3HhjepTjUhUC8FLk4jMQIBvq1BcORniwuTFHjPVhVo,3784
|
|
101
102
|
sunholo/tools/__init__.py,sha256=5NuYpwwTX81qGUWvgwfItoSLXteNnp7KjgD7IPZUFjI,53
|
|
102
|
-
sunholo/tools/web_browser.py,sha256=
|
|
103
|
+
sunholo/tools/web_browser.py,sha256=RQrkQN1shi5zYsjngyKSXZ1Lz9rrUrsFYTI_zHCsHRE,29079
|
|
103
104
|
sunholo/utils/__init__.py,sha256=Hv02T5L2zYWvCso5hzzwm8FQogwBq0OgtUbN_7Quzqc,89
|
|
104
105
|
sunholo/utils/api_key.py,sha256=Ct4bIAQZxzPEw14hP586LpVxBAVi_W9Serpy0BK-7KI,244
|
|
105
106
|
sunholo/utils/big_context.py,sha256=gJIP7_ZL-YSLhOMq8jmFTMqH1wq8eB1NK7oKPeZAq2s,5578
|
|
@@ -113,13 +114,13 @@ sunholo/utils/timedelta.py,sha256=BbLabEx7_rbErj_YbNM0MBcaFN76DC4PTe4zD2ucezg,49
|
|
|
113
114
|
sunholo/utils/user_ids.py,sha256=SQd5_H7FE7vcTZp9AQuQDWBXd4FEEd7TeVMQe1H4Ny8,292
|
|
114
115
|
sunholo/utils/version.py,sha256=P1QAJQdZfT2cMqdTSmXmcxrD2PssMPEGM-WI6083Fck,237
|
|
115
116
|
sunholo/vertex/__init__.py,sha256=XH7FUKxdIgN9H2iDcWxL3sRnVHC3297G24RqEn4Ob0Y,240
|
|
116
|
-
sunholo/vertex/extensions_class.py,sha256=
|
|
117
|
+
sunholo/vertex/extensions_class.py,sha256=vjYOaqU-KQsqkDsJSWBmydzMA-kY-PqZ0j_GUb8ZlNY,16884
|
|
117
118
|
sunholo/vertex/init.py,sha256=-w7b9GKsyJnAJpYHYz6_zBUtmeJeLXlEkgOfwoe4DEI,2715
|
|
118
119
|
sunholo/vertex/memory_tools.py,sha256=pomHrDKqvY8MZxfUqoEwhdlpCvSGP6KmFJMVKOimXjs,6842
|
|
119
120
|
sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
|
|
120
|
-
sunholo-0.
|
|
121
|
-
sunholo-0.
|
|
122
|
-
sunholo-0.
|
|
123
|
-
sunholo-0.
|
|
124
|
-
sunholo-0.
|
|
125
|
-
sunholo-0.
|
|
121
|
+
sunholo-0.75.1.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
|
|
122
|
+
sunholo-0.75.1.dist-info/METADATA,sha256=GDyIzrBHNdyewLXAJ0_PcLkgMlp6scIbI5sEL8izPrY,7010
|
|
123
|
+
sunholo-0.75.1.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
124
|
+
sunholo-0.75.1.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
|
|
125
|
+
sunholo-0.75.1.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
|
|
126
|
+
sunholo-0.75.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|