sunholo 0.56.7__tar.gz → 0.57.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 (98) hide show
  1. {sunholo-0.56.7 → sunholo-0.57.1}/PKG-INFO +2 -2
  2. {sunholo-0.56.7 → sunholo-0.57.1}/setup.py +1 -1
  3. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/flask/qna_routes.py +14 -3
  4. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/splitter.py +7 -6
  5. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/cli/cli.py +7 -7
  6. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/langfuse/prompts.py +14 -0
  7. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/qna/parsers.py +20 -3
  8. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/streaming/content_buffer.py +1 -4
  9. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/streaming/streaming.py +3 -10
  10. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo.egg-info/PKG-INFO +2 -2
  11. {sunholo-0.56.7 → sunholo-0.57.1}/LICENSE.txt +0 -0
  12. {sunholo-0.56.7 → sunholo-0.57.1}/MANIFEST.in +0 -0
  13. {sunholo-0.56.7 → sunholo-0.57.1}/README.md +0 -0
  14. {sunholo-0.56.7 → sunholo-0.57.1}/setup.cfg +0 -0
  15. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/__init__.py +0 -0
  16. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/__init__.py +0 -0
  17. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/chat_history.py +0 -0
  18. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/dispatch_to_qa.py +0 -0
  19. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/fastapi/__init__.py +0 -0
  20. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/fastapi/base.py +0 -0
  21. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/fastapi/qna_routes.py +0 -0
  22. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/flask/__init__.py +0 -0
  23. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/flask/base.py +0 -0
  24. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/langserve.py +0 -0
  25. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/pubsub.py +0 -0
  26. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/route.py +0 -0
  27. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/special_commands.py +0 -0
  28. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/agents/test_chat_history.py +0 -0
  29. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/archive/__init__.py +0 -0
  30. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/archive/archive.py +0 -0
  31. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/auth/__init__.py +0 -0
  32. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/auth/run.py +0 -0
  33. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/bots/__init__.py +0 -0
  34. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/bots/discord.py +0 -0
  35. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/bots/webapp.py +0 -0
  36. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/__init__.py +0 -0
  37. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/data_to_embed_pubsub.py +0 -0
  38. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/doc_handling.py +0 -0
  39. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/images.py +0 -0
  40. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/loaders.py +0 -0
  41. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/message_data.py +0 -0
  42. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/pdfs.py +0 -0
  43. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/chunker/publish.py +0 -0
  44. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/cli/__init__.py +0 -0
  45. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/components/__init__.py +0 -0
  46. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/components/llm.py +0 -0
  47. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/components/prompt.py +0 -0
  48. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/components/retriever.py +0 -0
  49. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/components/vectorstore.py +0 -0
  50. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/__init__.py +0 -0
  51. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/alloydb.py +0 -0
  52. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/database.py +0 -0
  53. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/lancedb.py +0 -0
  54. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/sql/sb/create_function.sql +0 -0
  55. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  56. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/sql/sb/create_table.sql +0 -0
  57. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  58. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/sql/sb/return_sources.sql +0 -0
  59. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/sql/sb/setup.sql +0 -0
  60. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/static_dbs.py +0 -0
  61. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/database/uuid.py +0 -0
  62. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/embedder/__init__.py +0 -0
  63. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/embedder/embed_chunk.py +0 -0
  64. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/gcs/__init__.py +0 -0
  65. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/gcs/add_file.py +0 -0
  66. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/gcs/download_url.py +0 -0
  67. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/gcs/metadata.py +0 -0
  68. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/langfuse/__init__.py +0 -0
  69. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/langfuse/callback.py +0 -0
  70. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/llamaindex/__init__.py +0 -0
  71. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/llamaindex/generate.py +0 -0
  72. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/llamaindex/import_files.py +0 -0
  73. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/logging.py +0 -0
  74. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/lookup/__init__.py +0 -0
  75. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/lookup/model_lookup.yaml +0 -0
  76. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/patches/__init__.py +0 -0
  77. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/patches/langchain/__init__.py +0 -0
  78. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/patches/langchain/lancedb.py +0 -0
  79. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/patches/langchain/vertexai.py +0 -0
  80. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/pubsub/__init__.py +0 -0
  81. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/pubsub/process_pubsub.py +0 -0
  82. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/pubsub/pubsub_manager.py +0 -0
  83. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/qna/__init__.py +0 -0
  84. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/qna/retry.py +0 -0
  85. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/streaming/__init__.py +0 -0
  86. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/streaming/langserve.py +0 -0
  87. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/summarise/__init__.py +0 -0
  88. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/summarise/summarise.py +0 -0
  89. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/utils/__init__.py +0 -0
  90. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/utils/config.py +0 -0
  91. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/utils/gcp.py +0 -0
  92. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo/utils/parsers.py +0 -0
  93. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo.egg-info/SOURCES.txt +0 -0
  94. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo.egg-info/dependency_links.txt +0 -0
  95. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo.egg-info/entry_points.txt +0 -0
  96. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo.egg-info/requires.txt +0 -0
  97. {sunholo-0.56.7 → sunholo-0.57.1}/sunholo.egg-info/top_level.txt +0 -0
  98. {sunholo-0.56.7 → sunholo-0.57.1}/test/test_dispatch_to_qa.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.56.7
3
+ Version: 0.57.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.56.7.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.57.1.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,7 +1,7 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
3
  # Define your base version
4
- version = '0.56.7'
4
+ version = '0.57.1'
5
5
 
6
6
  setup(
7
7
  name='sunholo',
@@ -29,9 +29,16 @@ try:
29
29
  except ImportError:
30
30
  print("No flask installed for agents.flask.register_qna_routes, install via `pip install sunholo[http]`")
31
31
 
32
+ try:
33
+ from langfuse.decorators import langfuse_context, observe
34
+ except ImportError as err:
35
+ print(f"No langfuse installed for agents.flask.register_qna_routes, install via `pip install sunholo[http]` - {str(err)}")
36
+
37
+
32
38
  def register_qna_routes(app, stream_interpreter, vac_interpreter):
33
39
 
34
40
  @app.route('/vac/streaming/<vector_name>', methods=['POST'])
41
+ @observe()
35
42
  def stream_qa(vector_name):
36
43
  prep = prep_vac(request, vector_name)
37
44
  log.debug(f"Processing prep: {prep}")
@@ -54,6 +61,7 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
54
61
  model=vac_config.get("model") or vac_config.get("llm")
55
62
  )
56
63
 
64
+ @observe()
57
65
  def generate_response_content():
58
66
 
59
67
  chunks = ""
@@ -77,9 +85,9 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
77
85
  generation.end(output=json.dumps(chunk))
78
86
  span.end(output=json.dumps(chunk))
79
87
  trace.update(output=json.dumps(chunk))
80
- yield f"###JSON_START###{json.dumps(chunk)}###JSON_END###"
81
88
 
82
- return
89
+ return json.dumps(chunk)
90
+
83
91
  else:
84
92
  # Otherwise, we yield the plain text chunks as they come in.
85
93
  if chunk:
@@ -100,6 +108,7 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
100
108
  return response
101
109
 
102
110
  @app.route('/vac/<vector_name>', methods=['POST'])
111
+ @observe()
103
112
  def process_qna(vector_name):
104
113
  prep = prep_vac(request, vector_name)
105
114
  log.debug(f"Processing prep: {prep}")
@@ -177,7 +186,9 @@ def create_langfuse_trace(request, vector_name):
177
186
  )
178
187
 
179
188
  def prep_vac(request, vector_name):
180
- trace = create_langfuse_trace(request, vector_name)
189
+ #trace = create_langfuse_trace(request, vector_name)
190
+ trace = None
191
+ span = None
181
192
  data = request.get_json()
182
193
  log.info(f"vac/{vector_name} got data: {data}")
183
194
  config, _ = load_config("config/llm_config.yaml")
@@ -32,12 +32,13 @@ def chunk_doc_to_docs(documents: list, extension: str = ".md", min_size: int = 8
32
32
  docstore_doc_id, documents = send_doc_to_docstore(documents, vector_name=vector_name)
33
33
 
34
34
  doc_summaries = summarise_docs(documents, vector_name=vector_name)
35
- for doc in documents:
36
- # Assuming each doc has a unique identifier in its metadata under 'objectId'
37
- objectId = doc.metadata.get("objectId")
38
- if objectId and objectId in doc_summaries:
39
- # If the objectId is found in doc_summaries, add the summary location to the document's metadata
40
- doc.metadata["summary_location"] = doc_summaries[objectId]
35
+ if doc_summaries:
36
+ for doc in documents:
37
+ # Assuming each doc has a unique identifier in its metadata under 'objectId'
38
+ objectId = doc.metadata.get("objectId")
39
+ if objectId and objectId in doc_summaries:
40
+ # If the objectId is found in doc_summaries, add the summary location to the document's metadata
41
+ doc.metadata["summary_location"] = doc_summaries[objectId]
41
42
 
42
43
  # Combine entire documents that are smaller than min_size
43
44
  combined_documents_content = ""
@@ -1,8 +1,8 @@
1
1
  import argparse
2
2
  try:
3
- from google.cloud import build_v1
3
+ from google.cloud.devtools import cloudbuild_v1
4
4
  except ImportError:
5
- build_v1 = None
5
+ cloudbuild_v1 = None
6
6
 
7
7
  from ..logging import log
8
8
 
@@ -16,21 +16,21 @@ def trigger_build(args):
16
16
  Example:
17
17
  trigger_build(args) where args contains project_id, trigger_id, repo_name, and branch_name.
18
18
  """
19
- if not build_v1:
19
+ if not cloudbuild_v1:
20
20
  log.warning("Can't deploy - google-cloud-build not installed, enable via `pip install sunholo[gcp]")
21
21
 
22
22
  return None
23
23
 
24
- client = build_v1.services.cloud_build.CloudBuildClient()
24
+ client = cloudbuild_v1.CloudBuildClient()
25
25
  # Assuming the build source uses the path to the cloudbuild.yaml if specified.
26
- source = build_v1.RepoSource(
26
+ source = cloudbuild_v1.RepoSource(
27
27
  project_id=args.project_id,
28
28
  repo_name=args.repo_name,
29
29
  branch_name=args.branch_name,
30
30
  substitutions=args.substitutions,
31
31
  dir=args.config_path # Path to directory containing cloudbuild.yaml
32
32
  )
33
- request = build_v1.RunBuildTriggerRequest(
33
+ request = cloudbuild_v1.RunBuildTriggerRequest(
34
34
  project_id=args.project_id,
35
35
  trigger_id=args.trigger_id,
36
36
  source=source
@@ -62,7 +62,7 @@ def main(args=None):
62
62
 
63
63
  Example commands:
64
64
  ```bash
65
- sunholo deploy --project_id "my-gcp-project" --trigger_id "my-trigger-id" --repo_name "my-repo" --branch_name "dev" --config_path "app/vac/my_vac/"
65
+ sunholo deploy --vac edmonbrain --config=llm_config.yaml
66
66
  ```
67
67
  """
68
68
  parser = argparse.ArgumentParser(description="sunholo CLI tool for deploying applications using Google Cloud Build.")
@@ -3,6 +3,20 @@ from ..utils import load_config_key
3
3
 
4
4
  # Load the YAML file
5
5
  def load_prompt_from_yaml(key, prefix="sunholo", file_path=None):
6
+ """
7
+ Returns a string you can use with Langfuse PromptTemplate.from_template()
8
+
9
+ Will first try to load from the Langfuse prompt library, if unavailable will look in promptConfig type file.
10
+
11
+ Langfuse prompts have {{ two braces }}, Langchain prompts have { one brace }.
12
+
13
+ Example:
14
+
15
+ ```python
16
+ from sunholo.langfuse.prompts import load_prompt_from_yaml
17
+ from langchain_core.prompts import PromptTemplate
18
+
19
+ """
6
20
  from langfuse import Langfuse
7
21
 
8
22
  # Initialize Langfuse client
@@ -21,18 +21,35 @@ def document_to_dict(document):
21
21
  }
22
22
 
23
23
  def parse_output(bot_output):
24
+ """
25
+ Parses VAC output assuming it has an 'answer' and an optional 'source_documents' key
26
+
27
+ """
24
28
  if isinstance(bot_output, str):
29
+
25
30
  return {"answer": bot_output}
31
+
26
32
  if isinstance(bot_output, dict) and 'source_documents' in bot_output:
27
- if 'source_documents' in bot_output:
28
- bot_output['source_documents'] = [document_to_dict(doc) for doc in bot_output['source_documents']]
29
- if bot_output.get("answer", None) is None or bot_output.get("answer") == "":
33
+ bot_output['source_documents'] = [document_to_dict(doc) for doc in bot_output['source_documents']]
34
+ if not bot_output.get("answer") or bot_output.get("answer") == "":
35
+ bot_output['answer'] = "(No text was returned)"
36
+
37
+ return bot_output
38
+
39
+ elif isinstance(bot_output, dict) and 'metadata' in bot_output and isinstance(bot_output.get('metadata')) and 'source_documents' in bot_output.get('metadata'):
40
+ metadata = bot_output.get('metadata')
41
+ bot_output['source_documents'] = [document_to_dict(doc) for doc in metadata['source_documents']]
42
+ if not bot_output.get("answer") or bot_output.get("answer") == "":
30
43
  bot_output['answer'] = "(No text was returned)"
44
+
31
45
  return bot_output
46
+
32
47
  elif isinstance(bot_output, dict):
33
48
  if not bot_output.get("answer"):
34
49
  raise ValueError(f"VAC output was not a string or a dict with the key 'answer' - got: {bot_output}")
35
50
  else:
51
+
36
52
  return bot_output
53
+
37
54
  else:
38
55
  log.error(f"Couldn't parse output for:\n {bot_output}")
@@ -51,7 +51,6 @@ class ContentBuffer:
51
51
  Adds the given text to the existing content of the buffer.
52
52
  """
53
53
  self.content += text
54
- log.debug(f"Written {text} to buffer")
55
54
 
56
55
  def read(self) -> str:
57
56
  """
@@ -61,8 +60,7 @@ class ContentBuffer:
61
60
  str: The content of the buffer.
62
61
 
63
62
  Provides the entire content stored in the buffer.
64
- """
65
- log.debug(f"Read content from buffer")
63
+ """
66
64
  return self.content
67
65
 
68
66
  def clear(self):
@@ -71,7 +69,6 @@ class ContentBuffer:
71
69
 
72
70
  Empties the buffer content, resetting it to an empty string.
73
71
  """
74
- log.debug(f"Clearing content buffer")
75
72
  self.content = ""
76
73
 
77
74
 
@@ -39,8 +39,6 @@ def start_streaming_chat(question,
39
39
  if not check_kwargs_support(qna_func):
40
40
  yield "No **kwargs in qna_func - please add it"
41
41
 
42
- # Immediately yield to indicate the process has started.
43
- yield "Thinking...\n"
44
42
  log.info(f"Streaming chat with wait time {wait_time} seconds and timeout {timeout} seconds and kwargs {kwargs}")
45
43
  # Initialize the chat
46
44
  content_buffer = ContentBuffer()
@@ -82,12 +80,6 @@ def start_streaming_chat(question,
82
80
  yield content_to_send
83
81
  content_buffer.clear()
84
82
  start = time.time() # reset timeout
85
- else:
86
- if time.time() - first_start < wait_time:
87
- # If the initial wait period hasn't passed yet, keep sending "..."
88
- yield "..."
89
- else:
90
- log.info("No content to send")
91
83
 
92
84
  elapsed_time = time.time() - start
93
85
  if elapsed_time > timeout: # If the elapsed time exceeds the timeout
@@ -162,9 +154,10 @@ async def start_streaming_chat_async(question, vector_name, qna_func, chat_histo
162
154
  The `start_streaming_chat_async` function is used in a coroutine that prints messages as they are generated.
163
155
  """
164
156
 
165
- yield "Thinking...\n"
166
157
  log.info(f"Streaming chat with wait time {wait_time} seconds and timeout {timeout} seconds and kwargs {kwargs}")
167
-
158
+ if not check_kwargs_support(qna_func):
159
+ yield "No **kwargs in qna_func - please add it"
160
+
168
161
  content_buffer = ContentBuffer()
169
162
  chat_callback_handler = BufferStreamingStdOutCallbackHandler(content_buffer=content_buffer, tokens=".!?\n")
170
163
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.56.7
3
+ Version: 0.57.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.56.7.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.57.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