sunholo 0.140.12__py3-none-any.whl → 0.141.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.
@@ -441,10 +441,10 @@ def create_message_element(message: dict):
441
441
  ```
442
442
  """
443
443
  if 'text' in message: # This is a Slack or Google Chat message
444
- log.info(f"Found text element - {message['text']}")
444
+ #log.info(f"Found text element - {message['text']}")
445
445
  return message['text']
446
446
  elif 'content' in message: # Discord or OpenAI history message
447
- log.info(f"Found content element - {message['content']}")
447
+ #log.info(f"Found content element - {message['content']}")
448
448
  return message['content']
449
449
  else:
450
450
  raise KeyError(f"Could not extract 'content' or 'text' element from message: {message}, {type(message)}")
@@ -280,7 +280,7 @@ class DiscoveryEngineClient:
280
280
  # Use async_search_with_filters with filter_str=None to perform a regular search
281
281
  return await self.async_search_with_filters(
282
282
  query=query,
283
- filter_str=None,
283
+ filter_str=filter_str,
284
284
  num_previous_chunks=num_previous_chunks,
285
285
  num_next_chunks=num_next_chunks,
286
286
  page_size=page_size,
sunholo/utils/mime.py CHANGED
@@ -83,7 +83,6 @@ def get_mime_type_gemini(file_path:str) -> str:
83
83
 
84
84
  # Define the mapping of extensions to MIME types
85
85
  mime_types = {
86
-
87
86
  # Images
88
87
  'png': 'image/png',
89
88
  'jpg': 'image/jpeg',
@@ -111,7 +110,20 @@ def get_mime_type_gemini(file_path:str) -> str:
111
110
  'rtf': 'text/rtf',
112
111
 
113
112
  # Special case: JSON files are treated as plain text
114
- 'json': 'text/plain'
113
+ 'json': 'text/plain',
114
+
115
+ # Audio
116
+ 'mp3': 'audio/mp3',
117
+ 'mpeg': 'audio/mpeg',
118
+ 'wav': 'audio/wav',
119
+
120
+ # Video
121
+ 'mov': 'video/mov',
122
+ 'mp4': 'video/mp4',
123
+ 'mpg': 'video/mpeg',
124
+ 'avi': 'video/avi',
125
+ 'wmv': 'video/wmv',
126
+ 'flv': 'video/flv'
115
127
  }
116
128
 
117
129
  # Return the appropriate MIME type, defaulting to None if unknown
@@ -0,0 +1,25 @@
1
+
2
+
3
+ def convert_composite_to_native(value):
4
+ """
5
+ Recursively converts a proto MapComposite or RepeatedComposite object to native Python types.
6
+
7
+ Args:
8
+ value: The proto object, which could be a MapComposite, RepeatedComposite, or a primitive.
9
+
10
+ Returns:
11
+ The equivalent Python dictionary, list, or primitive type.
12
+ """
13
+ import proto
14
+
15
+ if isinstance(value, proto.marshal.collections.maps.MapComposite):
16
+ # Convert MapComposite to a dictionary, recursively processing its values
17
+ return {key: convert_composite_to_native(val) for key, val in value.items()}
18
+ elif isinstance(value, proto.marshal.collections.repeated.RepeatedComposite):
19
+ # Convert RepeatedComposite to a list, recursively processing its elements
20
+ return [convert_composite_to_native(item) for item in value]
21
+ else:
22
+ # If it's a primitive value, return it as is
23
+ return value
24
+
25
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sunholo
3
- Version: 0.140.12
3
+ Version: 0.141.1
4
4
  Summary: AI DevOps - a package to help deploy GenAI to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
@@ -255,7 +255,7 @@ vac:
255
255
  sunholo vac chat my-agent
256
256
  ```
257
257
 
258
- 4. **Deploy to Google Cloud Run:**
258
+ 4. **Run your agent as a local Flask app:**
259
259
  ```bash
260
260
  sunholo deploy my-agent
261
261
  ```
@@ -369,102 +369,132 @@ vac:
369
369
 
370
370
  ```bash
371
371
  # Project Management
372
- sunholo init <project-name> # Create new project
372
+ sunholo init <project-name> # Create new project from template
373
373
  sunholo list-configs # List all configurations
374
- sunholo list-configs --validate # Validate configs
374
+ sunholo list-configs --validate # Validate configurations
375
375
 
376
376
  # Development
377
377
  sunholo vac chat <vac-name> # Chat with a VAC locally
378
- sunholo vac list # List available VACs
378
+ sunholo vac list # List available VACs
379
+ sunholo vac get-url <vac-name> # Get Cloud Run URL for a VAC
379
380
  sunholo proxy start <service> # Start local proxy to cloud service
380
-
381
- # Deployment
382
- sunholo deploy <vac-name> # Deploy to Cloud Run
383
- sunholo deploy <vac-name> --dev # Deploy to dev environment
381
+ sunholo proxy list # List running proxies
382
+ sunholo deploy <vac-name> # Run Flask app locally
384
383
 
385
384
  # Document Processing
386
- sunholo embed <vac-name> # Embed documents
385
+ sunholo embed <vac-name> # Process and embed documents
387
386
  sunholo merge-text <folder> <output> # Merge files for context
388
387
 
389
388
  # Cloud Services
390
- sunholo discovery-engine create <name> # Create Discovery Engine
391
- sunholo proxy list # List running proxies
389
+ sunholo discovery-engine create <name> # Create Discovery Engine instance
390
+ sunholo vertex list-extensions # List Vertex AI extensions
391
+ sunholo swagger <vac-name> # Generate OpenAPI spec
392
+
393
+ # Integration Tools
394
+ sunholo excel-init # Initialize Excel plugin
395
+ sunholo llamaindex <query> # Query with LlamaIndex
396
+ sunholo mcp list-tools # List MCP tools
397
+ sunholo tts <text> # Text-to-speech synthesis
392
398
  ```
393
399
 
394
400
  ## 📝 Examples
395
401
 
396
- ### Vertex AI Chat with Memory
402
+ ### Chat with History Extraction
397
403
 
398
404
  ```python
399
405
  from sunholo.utils import ConfigManager
400
406
  from sunholo.components import pick_llm
401
- from sunholo.agents import memory_client
407
+ from sunholo.agents import extract_chat_history
402
408
 
403
409
  config = ConfigManager('my-agent')
404
410
  llm = pick_llm(config=config)
405
- memory = memory_client(config=config)
406
411
 
407
- # Chat with context
408
- response = llm.invoke("What is Google Cloud?")
409
- memory.add_message("user", "What is Google Cloud?")
410
- memory.add_message("assistant", response)
412
+ # Extract chat history from messages
413
+ chat_history = [
414
+ {"role": "user", "content": "Hello"},
415
+ {"role": "assistant", "content": "Hi there!"}
416
+ ]
417
+ history_str = extract_chat_history(chat_history)
418
+
419
+ # Use in prompt
420
+ response = llm.invoke(f"Given this history:\n{history_str}\n\nUser: How are you?")
411
421
  ```
412
422
 
413
- ### Document Processing with Discovery Engine
423
+ ### Document Processing with Chunker
414
424
 
415
425
  ```python
416
- from sunholo.discovery_engine import DiscoveryEngineClient
417
- from sunholo.chunker import chunk_doc
426
+ from sunholo.chunker import direct_file_to_embed
427
+ from sunholo.utils import ConfigManager
418
428
 
419
- # Initialize client
420
- client = DiscoveryEngineClient(
421
- project_id='my-project',
422
- data_store_id='my-datastore'
429
+ config = ConfigManager('my-agent')
430
+
431
+ # Process a file directly
432
+ result = direct_file_to_embed(
433
+ "document.pdf",
434
+ embed_prefix="doc",
435
+ metadata={"source": "user_upload"},
436
+ vectorstore=config.vacConfig("vectorstore")
423
437
  )
438
+ ```
424
439
 
425
- # Process and index document
426
- chunks = chunk_doc.chunk_file("document.pdf", chunk_size=1000)
427
- client.import_documents(chunks)
440
+ ### Vertex AI with Memory Tools
428
441
 
429
- # Search
430
- results = client.search("What is the main topic?")
442
+ ```python
443
+ from sunholo.vertex import get_vertex_memories
444
+ from sunholo.utils import ConfigManager
445
+
446
+ config = ConfigManager('my-agent')
447
+
448
+ # Get Vertex AI memory configuration
449
+ memory_config = get_vertex_memories(config)
450
+
451
+ # Use with Vertex AI
452
+ if memory_config:
453
+ print(f"Memory tools configured: {memory_config}")
431
454
  ```
432
455
 
433
- ### Streaming Flask API
456
+ ### Streaming Response with Flask
434
457
 
435
458
  ```python
436
- from sunholo.agents import dispatch_to_qa
459
+ from sunholo.agents import send_to_qa
460
+ from flask import Response, request
437
461
 
438
462
  @app.route('/vac/streaming/<vac_name>', methods=['POST'])
439
463
  def streaming_endpoint(vac_name):
440
464
  question = request.json.get('user_input')
441
465
 
442
466
  def generate():
443
- for chunk in dispatch_to_qa(
467
+ # Stream responses from the QA system
468
+ response = send_to_qa(
444
469
  question,
445
470
  vac_name=vac_name,
446
471
  stream=True
447
- ):
448
- yield f"data: {chunk}\n\n"
472
+ )
473
+ if hasattr(response, '__iter__'):
474
+ for chunk in response:
475
+ yield f"data: {chunk}\n\n"
476
+ else:
477
+ yield f"data: {response}\n\n"
449
478
 
450
479
  return Response(generate(), content_type='text/event-stream')
451
480
  ```
452
481
 
453
- ### Deploy from Template
482
+ ### Discovery Engine Integration
454
483
 
455
- ```bash
456
- # Create from template
457
- sunholo init my-api --template agent
458
-
459
- # Customize configuration
460
- cd my-api
461
- vi config/vac_config.yaml
484
+ ```python
485
+ from sunholo.discovery_engine import DiscoveryEngineClient
462
486
 
463
- # Test locally
464
- sunholo vac chat my-agent --local
487
+ # Initialize client
488
+ client = DiscoveryEngineClient(
489
+ project_id='my-project',
490
+ data_store_id='my-datastore'
491
+ )
465
492
 
466
- # Deploy to production
467
- sunholo deploy my-agent
493
+ # Search documents
494
+ results = client.search("What is Vertex AI?")
495
+ for result in results:
496
+ print(f"Content: {result.chunk.content}")
497
+ print(f"Score: {result.relevance_score}")
468
498
  ```
469
499
 
470
500
  ## 🧪 Testing
@@ -2,7 +2,7 @@ sunholo/__init__.py,sha256=InRbX4V0-qdNHo9zYH3GEye7ASLR6LX8-SMvPV4Jsaw,1212
2
2
  sunholo/custom_logging.py,sha256=JXZTnXp_DixP3jwYfKw4LYRDS9IuTq7ctCgfZbI2rxA,22023
3
3
  sunholo/langchain_types.py,sha256=uZ4zvgej_f7pLqjtu4YP7qMC_eZD5ym_5x4pyvA1Ih4,1834
4
4
  sunholo/agents/__init__.py,sha256=AauG3l0y4r5Fzx1zJfZ634M4o-0o7B7J5T8k_gPvNqE,370
5
- sunholo/agents/chat_history.py,sha256=e2NmiooaRUxKGr_aoU05rzhHi3VsKjbZZmzeDr2yJJE,17780
5
+ sunholo/agents/chat_history.py,sha256=gRuIUyU-53A72Q17SmSgf6Ok3YO8hKAZhsc64976018,17782
6
6
  sunholo/agents/dispatch_to_qa.py,sha256=NHihwAoCJ5_Lk11e_jZnucVUGQyZHCB-YpkfMHBCpQk,8882
7
7
  sunholo/agents/langserve.py,sha256=C46ph2mnygr6bdHijYWYyfQDI9ylAF0_9Kx2PfcCJpU,4414
8
8
  sunholo/agents/pubsub.py,sha256=TscZN_6am6DfaQkC-Yl18ZIBOoLE-0nDSiil6GpQEh4,1344
@@ -74,7 +74,7 @@ sunholo/discovery_engine/__init__.py,sha256=hLgqRDJ22Aov9o2QjAEfsVgnL3kMdM-g5p8R
74
74
  sunholo/discovery_engine/chunker_handler.py,sha256=wkvXl4rFtYfN6AZUKdW9_QD49Whf77BukDbO82UwlAg,7480
75
75
  sunholo/discovery_engine/cli.py,sha256=tsKqNSDCEsDTz5-wuNwjttb3Xt35D97-KyyEiaqolMQ,35628
76
76
  sunholo/discovery_engine/create_new.py,sha256=WUi4_xh_dFaGX3xA9jkNKZhaR6LCELjMPeRb0hyj4FU,1226
77
- sunholo/discovery_engine/discovery_engine_client.py,sha256=VSInta9IZE_LmA3CFYqxLpxdoB7w0IuSRSFM2UnmrRk,63705
77
+ sunholo/discovery_engine/discovery_engine_client.py,sha256=0gMVWunSndh7uyT4IMSIkDKrNec3CLKX-om0eIjdC9o,63711
78
78
  sunholo/discovery_engine/get_ai_search_chunks.py,sha256=I6Dt1CznqEvE7XIZ2PkLqopmjpO96iVEWJJqL5cJjOU,5554
79
79
  sunholo/embedder/__init__.py,sha256=sI4N_CqgEVcrMDxXgxKp1FsfsB4FpjoXgPGkl4N_u4I,44
80
80
  sunholo/embedder/embed_chunk.py,sha256=did2pKkWM2o0KkRcb0H9l2x_WjCq6OyuHDxGbITFKPM,6530
@@ -155,8 +155,9 @@ sunholo/utils/config_class.py,sha256=U0xwyCz68KCJgzyhXd0AmbFnstMBFvZMedb-lLKKa5Q
155
155
  sunholo/utils/config_schema.py,sha256=Wv-ncitzljOhgbDaq9qnFqH5LCuxNv59dTGDWgd1qdk,4189
156
156
  sunholo/utils/gcp.py,sha256=lus1HH8YhFInw6QRKwfvKZq-Lz-2KQg4ips9v1I_3zE,4783
157
157
  sunholo/utils/gcp_project.py,sha256=Fa0IhCX12bZ1ctF_PKN8PNYd7hihEUfb90kilBfUDjg,1411
158
- sunholo/utils/mime.py,sha256=mELAiZcGa69PshBxV7y770E0K09YfX4Z4ZRBPL-7gXs,3352
158
+ sunholo/utils/mime.py,sha256=HqquYfnhekjzmzFXdP9DtO50ZljNV8swjcOlMDH8GTs,3656
159
159
  sunholo/utils/parsers.py,sha256=wES0fRn3GONoymRXOXt-z62HCoOiUvvFXa-MfKfjCls,6421
160
+ sunholo/utils/proto_convert.py,sha256=IMd4d7nat2MkJDueDiY2jKbQ7KSJ6tNd2P0ANxDq1mc,927
160
161
  sunholo/utils/timedelta.py,sha256=BbLabEx7_rbErj_YbNM0MBcaFN76DC4PTe4zD2ucezg,493
161
162
  sunholo/utils/user_ids.py,sha256=SQd5_H7FE7vcTZp9AQuQDWBXd4FEEd7TeVMQe1H4Ny8,292
162
163
  sunholo/utils/version.py,sha256=P1QAJQdZfT2cMqdTSmXmcxrD2PssMPEGM-WI6083Fck,237
@@ -168,9 +169,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
168
169
  sunholo/vertex/memory_tools.py,sha256=tBZxqVZ4InTmdBvLlOYwoSEWu4-kGquc-gxDwZCC4FA,7667
169
170
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
170
171
  sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
171
- sunholo-0.140.12.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
172
- sunholo-0.140.12.dist-info/METADATA,sha256=UBt83NkXY5EpTwdtDF5LCOe2IsBXlR1TCVx9EoAuAOA,17116
173
- sunholo-0.140.12.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
174
- sunholo-0.140.12.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
175
- sunholo-0.140.12.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
176
- sunholo-0.140.12.dist-info/RECORD,,
172
+ sunholo-0.141.1.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
173
+ sunholo-0.141.1.dist-info/METADATA,sha256=Ett7hxu4MPWMTgGQyVNADbvuuPOWvXIVUl2aRLXgNn8,18292
174
+ sunholo-0.141.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
175
+ sunholo-0.141.1.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
176
+ sunholo-0.141.1.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
177
+ sunholo-0.141.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5