sunholo 0.91.2__tar.gz → 0.92.1__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 (160) hide show
  1. {sunholo-0.91.2 → sunholo-0.92.1}/PKG-INFO +2 -2
  2. {sunholo-0.91.2 → sunholo-0.92.1}/setup.py +1 -1
  3. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/alloydb_client.py +2 -5
  4. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/genai/process_funcs_cls.py +184 -1
  5. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo.egg-info/PKG-INFO +2 -2
  6. {sunholo-0.91.2 → sunholo-0.92.1}/LICENSE.txt +0 -0
  7. {sunholo-0.91.2 → sunholo-0.92.1}/MANIFEST.in +0 -0
  8. {sunholo-0.91.2 → sunholo-0.92.1}/README.md +0 -0
  9. {sunholo-0.91.2 → sunholo-0.92.1}/setup.cfg +0 -0
  10. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/__init__.py +0 -0
  11. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/__init__.py +0 -0
  12. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/chat_history.py +0 -0
  13. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/dispatch_to_qa.py +0 -0
  14. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/fastapi/__init__.py +0 -0
  15. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/fastapi/base.py +0 -0
  16. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/fastapi/qna_routes.py +0 -0
  17. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/flask/__init__.py +0 -0
  18. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/flask/base.py +0 -0
  19. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/flask/qna_routes.py +0 -0
  20. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/flask/vac_routes.py +0 -0
  21. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/langserve.py +0 -0
  22. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/pubsub.py +0 -0
  23. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/route.py +0 -0
  24. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/special_commands.py +0 -0
  25. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/agents/swagger.py +0 -0
  26. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/archive/__init__.py +0 -0
  27. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/archive/archive.py +0 -0
  28. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/auth/__init__.py +0 -0
  29. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/auth/gcloud.py +0 -0
  30. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/auth/refresh.py +0 -0
  31. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/auth/run.py +0 -0
  32. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/azure/__init__.py +0 -0
  33. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/azure/auth.py +0 -0
  34. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/azure/blobs.py +0 -0
  35. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/azure/event_grid.py +0 -0
  36. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/bots/__init__.py +0 -0
  37. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/bots/discord.py +0 -0
  38. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/bots/github_webhook.py +0 -0
  39. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/bots/webapp.py +0 -0
  40. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/__init__.py +0 -0
  41. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/azure.py +0 -0
  42. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/doc_handling.py +0 -0
  43. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/encode_metadata.py +0 -0
  44. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/images.py +0 -0
  45. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/loaders.py +0 -0
  46. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/message_data.py +0 -0
  47. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/pdfs.py +0 -0
  48. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/process_chunker_data.py +0 -0
  49. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/publish.py +0 -0
  50. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/pubsub.py +0 -0
  51. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/chunker/splitter.py +0 -0
  52. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/__init__.py +0 -0
  53. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/chat_vac.py +0 -0
  54. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/cli.py +0 -0
  55. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/cli_init.py +0 -0
  56. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/configs.py +0 -0
  57. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/deploy.py +0 -0
  58. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/embedder.py +0 -0
  59. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/merge_texts.py +0 -0
  60. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/run_proxy.py +0 -0
  61. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/sun_rich.py +0 -0
  62. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/swagger.py +0 -0
  63. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/cli/vertex.py +0 -0
  64. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/components/__init__.py +0 -0
  65. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/components/llm.py +0 -0
  66. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/components/retriever.py +0 -0
  67. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/components/vectorstore.py +0 -0
  68. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/custom_logging.py +0 -0
  69. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/__init__.py +0 -0
  70. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/alloydb.py +0 -0
  71. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/database.py +0 -0
  72. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/lancedb.py +0 -0
  73. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/sql/sb/create_function.sql +0 -0
  74. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  75. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/sql/sb/create_table.sql +0 -0
  76. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  77. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/sql/sb/return_sources.sql +0 -0
  78. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/sql/sb/setup.sql +0 -0
  79. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/static_dbs.py +0 -0
  80. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/database/uuid.py +0 -0
  81. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/discovery_engine/__init__.py +0 -0
  82. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/discovery_engine/chunker_handler.py +0 -0
  83. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/discovery_engine/create_new.py +0 -0
  84. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/discovery_engine/discovery_engine_client.py +0 -0
  85. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/discovery_engine/get_ai_search_chunks.py +0 -0
  86. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/embedder/__init__.py +0 -0
  87. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/embedder/embed_chunk.py +0 -0
  88. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/excel/__init__.py +0 -0
  89. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/excel/plugin.py +0 -0
  90. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/gcs/__init__.py +0 -0
  91. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/gcs/add_file.py +0 -0
  92. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/gcs/download_folder.py +0 -0
  93. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/gcs/download_url.py +0 -0
  94. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/gcs/metadata.py +0 -0
  95. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/genai/__init__.py +0 -0
  96. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/genai/init.py +0 -0
  97. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/genai/safety.py +0 -0
  98. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/invoke/__init__.py +0 -0
  99. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/invoke/async_class.py +0 -0
  100. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/invoke/direct_vac_func.py +0 -0
  101. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/invoke/invoke_vac_utils.py +0 -0
  102. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/langfuse/__init__.py +0 -0
  103. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/langfuse/callback.py +0 -0
  104. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/langfuse/evals.py +0 -0
  105. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/langfuse/prompts.py +0 -0
  106. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/llamaindex/__init__.py +0 -0
  107. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/llamaindex/get_files.py +0 -0
  108. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/llamaindex/import_files.py +0 -0
  109. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/llamaindex/llamaindex_class.py +0 -0
  110. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/llamaindex/user_history.py +0 -0
  111. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/lookup/__init__.py +0 -0
  112. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/lookup/model_lookup.yaml +0 -0
  113. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/patches/__init__.py +0 -0
  114. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/patches/langchain/__init__.py +0 -0
  115. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/patches/langchain/lancedb.py +0 -0
  116. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/patches/langchain/vertexai.py +0 -0
  117. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/pubsub/__init__.py +0 -0
  118. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/pubsub/process_pubsub.py +0 -0
  119. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/pubsub/pubsub_manager.py +0 -0
  120. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/qna/__init__.py +0 -0
  121. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/qna/parsers.py +0 -0
  122. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/qna/retry.py +0 -0
  123. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/streaming/__init__.py +0 -0
  124. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/streaming/content_buffer.py +0 -0
  125. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/streaming/langserve.py +0 -0
  126. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/streaming/stream_lookup.py +0 -0
  127. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/streaming/streaming.py +0 -0
  128. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/summarise/__init__.py +0 -0
  129. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/summarise/summarise.py +0 -0
  130. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/terraform/__init__.py +0 -0
  131. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/terraform/tfvars_editor.py +0 -0
  132. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/tools/__init__.py +0 -0
  133. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/tools/web_browser.py +0 -0
  134. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/__init__.py +0 -0
  135. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/api_key.py +0 -0
  136. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/big_context.py +0 -0
  137. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/config.py +0 -0
  138. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/config_class.py +0 -0
  139. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/config_schema.py +0 -0
  140. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/gcp.py +0 -0
  141. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/gcp_project.py +0 -0
  142. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/parsers.py +0 -0
  143. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/timedelta.py +0 -0
  144. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/user_ids.py +0 -0
  145. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/utils/version.py +0 -0
  146. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/__init__.py +0 -0
  147. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/extensions_call.py +0 -0
  148. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/extensions_class.py +0 -0
  149. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/genai_functions.py +0 -0
  150. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/init.py +0 -0
  151. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/memory_tools.py +0 -0
  152. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/safety.py +0 -0
  153. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo/vertex/type_dict_to_json.py +0 -0
  154. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo.egg-info/SOURCES.txt +0 -0
  155. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo.egg-info/dependency_links.txt +0 -0
  156. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo.egg-info/entry_points.txt +0 -0
  157. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo.egg-info/requires.txt +0 -0
  158. {sunholo-0.91.2 → sunholo-0.92.1}/sunholo.egg-info/top_level.txt +0 -0
  159. {sunholo-0.91.2 → sunholo-0.92.1}/tests/test_chat_history.py +0 -0
  160. {sunholo-0.91.2 → sunholo-0.92.1}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.91.2
3
+ Version: 0.92.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.91.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.92.1.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- version = '0.91.2'
3
+ version = '0.92.1'
4
4
 
5
5
  setup(
6
6
  name='sunholo',
@@ -89,11 +89,8 @@ class AlloyDBClient:
89
89
  log.info("Build with Langchain engine - will use default service account for auth")
90
90
  self.engine = self._create_engine()
91
91
  self.engine_type = "langchain"
92
-
93
- if self.engine_type == "langchain":
94
- self.vectorstore = self.get_vectorstore()
95
- else:
96
- self.vectorstore = None
92
+
93
+ self.vectorstore = None
97
94
 
98
95
  def _build_instance_uri(self, project_id, region, cluster_name, instance_name):
99
96
  return f"projects/{project_id}/locations/{region}/clusters/{cluster_name}/instances/{instance_name}"
@@ -60,6 +60,11 @@ class GenAIFunctionProcessor:
60
60
 
61
61
  self.config = config
62
62
  self.funcs = self.construct_tools()
63
+
64
+ # Add default 'decide_to_go_on' if not provided in construct_tools
65
+ if 'decide_to_go_on' not in self.funcs:
66
+ self.funcs['decide_to_go_on'] = self.decide_to_go_on
67
+
63
68
  self.model_name = config.vacConfig("model") if config.vacConfig("llm") == "vertex" else "gemini-1.5-flash"
64
69
  self.last_api_requests_and_responses = []
65
70
  self._validate_functions()
@@ -317,4 +322,182 @@ class GenAIFunctionProcessor:
317
322
  return model
318
323
  except Exception as err:
319
324
  log.error(f"Error initializing model: {str(err)}")
320
- return None
325
+ return None
326
+
327
+ def run_agent_loop(self, chat, content, callback, guardrail_max=10):
328
+ """
329
+ Runs the agent loop, sending messages to the orchestrator, processing responses, and executing functions.
330
+
331
+ Args:
332
+ chat: The chat object for interaction with the orchestrator.
333
+ content: The initial content to send to the agent.
334
+ callback: The callback object for handling intermediate responses.
335
+ guardrail_max (int): The maximum number of iterations for the loop.
336
+
337
+ Returns:
338
+ tuple: (big_text, usage_metadata) from the loop execution.
339
+ """
340
+ guardrail = 0
341
+ big_text = ""
342
+ usage_metadata = {
343
+ "prompt_token_count": 0,
344
+ "candidates_token_count": 0,
345
+ "total_token_count": 0
346
+ }
347
+ functions_called =[]
348
+ function_results = []
349
+
350
+ while guardrail < guardrail_max:
351
+
352
+ callback.on_llm_new_token(
353
+ token=f"\n----Loop [{guardrail}] Start------\nFunctions:\n{self.funcs.keys()}\n"
354
+ )
355
+
356
+ content_parse = ""
357
+ for i, chunk in enumerate(content):
358
+ content_parse += f"\n - {i}) {chunk}"
359
+ content_parse += f"\n== End input content for loop [{guardrail}] =="
360
+
361
+ log.info(f"== Start input content for loop [{guardrail}]\n ## Content: {content_parse}")
362
+ this_text = "" # reset for this loop
363
+ response = []
364
+
365
+ try:
366
+ callback.on_llm_new_token(token="\n= Calling Agent\n")
367
+ response = chat.send_message(content, stream=True)
368
+
369
+ except Exception as e:
370
+ msg = f"Error sending {content} to model: {str(e)}"
371
+ log.info(msg)
372
+ callback.on_llm_new_token(token=msg)
373
+ break
374
+
375
+ loop_metadata = response.usage_metadata
376
+ if loop_metadata:
377
+ usage_metadata = {
378
+ "prompt_token_count": usage_metadata["prompt_token_count"] + (loop_metadata.prompt_token_count or 0),
379
+ "candidates_token_count": usage_metadata["candidates_token_count"] + (loop_metadata.candidates_token_count or 0),
380
+ "total_token_count": usage_metadata["total_token_count"] + (loop_metadata.total_token_count or 0),
381
+ }
382
+ callback.on_llm_new_token(token=(
383
+ "\n-- Agent response\n"
384
+ f"prompt_token_count: [{loop_metadata.prompt_token_count}]/[{usage_metadata['prompt_token_count']}] "
385
+ f"candidates_token_count: [{loop_metadata.candidates_token_count}]/[{usage_metadata['candidates_token_count']}] "
386
+ f"total_token_count: [{loop_metadata.total_token_count}]/[{usage_metadata['total_token_count']}] \n"
387
+ ))
388
+ loop_metadata = None
389
+
390
+ for chunk in response:
391
+ if not chunk:
392
+ continue
393
+
394
+ log.debug(f"[{guardrail}] {chunk=}")
395
+ try:
396
+ if hasattr(chunk, 'text') and isinstance(chunk.text, str):
397
+ token = chunk.text
398
+ callback.on_llm_new_token(token=token)
399
+ big_text += token
400
+ this_text += token
401
+ else:
402
+ log.info("skipping chunk with no text")
403
+
404
+ except ValueError as err:
405
+ callback.on_llm_new_token(token=f"{str(err)} for {chunk=}")
406
+
407
+ executed_responses = self.process_funcs(response)
408
+ log.info(f"[{guardrail}] {executed_responses=}")
409
+
410
+ if executed_responses:
411
+ callback.on_llm_new_token(token="\nAgent function execution:\n")
412
+ for executed_response in executed_responses:
413
+ token = ""
414
+ fn = executed_response.function_response.name
415
+ fn_args = executed_response.function_response.response.get("args")
416
+ fn_result = executed_response.function_response.response["result"]
417
+ fn_log = f"{fn}({fn_args})"
418
+ log.info(fn_log)
419
+ functions_called.append(fn_log)
420
+ function_results.append(fn_result)
421
+ callback.on_llm_new_token(token=f"\n--- function calling: {fn_log} ...\n")
422
+
423
+ try:
424
+ fn_result_json = json.loads(fn_result)
425
+ if not isinstance(fn_result_json, dict):
426
+ log.warning(f"{fn_result} was loaded but is not a dictionary")
427
+ fn_result_json = None
428
+ except json.JSONDecodeError:
429
+ log.warning(f"{fn_result} was not JSON decoded")
430
+ fn_result_json = None
431
+ except Exception as err:
432
+ log.warning(f"{fn_result} was not json decoded due to unknown exception: {str(err)}")
433
+ fn_result_json = None
434
+
435
+ if fn == "decide_to_go_on":
436
+ token = f"\n\n{'STOPPING' if not fn_result.get('go_on') else 'CONTINUE'}: {fn_result.get('chat_summary')}"
437
+ else:
438
+ token = f"--- function call result: {fn_log} ---"
439
+ if fn_result_json:
440
+ if fn_result_json.get('stdout'):
441
+ text = fn_result_json.get('stdout').encode('utf-8').decode('unicode_escape')
442
+ token += text
443
+ if fn_result_json.get('stderr'):
444
+ text = fn_result_json.get('stdout').encode('utf-8').decode('unicode_escape')
445
+ token += text
446
+ if not fn_result_json.get('stdout') and fn_result_json.get('stderr'):
447
+ token += f" - result:\n{fn_result}\n"
448
+ else:
449
+ token += f" - result:\n{fn_result}\n"
450
+
451
+ big_text += token
452
+ this_text += token
453
+ callback.on_llm_new_token(token=token)
454
+ else:
455
+ token = "\nNo function executions were found\n"
456
+ callback.on_llm_new_token(token=token)
457
+ big_text += token
458
+ this_text += token
459
+
460
+ if this_text:
461
+ content.append(f"Agent: {this_text}")
462
+ log.info(f"[{guardrail}] Updated content:\n{this_text}")
463
+ else:
464
+ log.warning(f"[{guardrail}] No content created this loop")
465
+ content.append(f"Agent: No response was found for loop [{guardrail}]")
466
+
467
+ callback.on_llm_new_token(
468
+ token=f"\n----Loop [{guardrail}] End------\n{usage_metadata}\n----------------------"
469
+ )
470
+
471
+ go_on_check = self.check_function_result("decide_to_go_on", {"go_on": False})
472
+ if go_on_check:
473
+ log.info("Breaking agent loop")
474
+ break
475
+
476
+ guardrail += 1
477
+ if guardrail > guardrail_max:
478
+ log.warning("Guardrail kicked in, more than 10 loops")
479
+ break
480
+
481
+ usage_metadata["functions_called"] = functions_called
482
+ usage_metadata["function_results"] = function_results
483
+
484
+ return big_text, usage_metadata
485
+
486
+ def decide_to_go_on(go_on: bool, chat_summary: str) -> dict:
487
+ """
488
+ Examine the chat history. If the answer to the user's question has been answered, then go_on=False.
489
+ If the chat history indicates the answer is still being looked for, then go_on=True.
490
+ If there is no chat history, then go_on=True.
491
+ If there is an error that can't be corrected or solved by you, then go_on=False.
492
+ If there is an error but you think you can solve it by correcting your function arguments (such as an incorrect source), then go_on=True
493
+ If you want to ask the user a question or for some more feedback, then go_on=False.
494
+ When calling, please also add a chat summary of why you think the function should be called to end.
495
+
496
+ Args:
497
+ go_on: boolean Whether to continue searching for an answer
498
+ chat_summary: string A brief explanation on why go_on is TRUE or FALSE
499
+
500
+ Returns:
501
+ boolean: True to carry on, False to continue
502
+ """
503
+ return {"go_on": go_on, "chat_summary": chat_summary}
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.91.2
3
+ Version: 0.92.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.91.2.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.92.1.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes