sunholo 0.62.13__tar.gz → 0.62.15__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 (119) hide show
  1. {sunholo-0.62.13 → sunholo-0.62.15}/PKG-INFO +2 -2
  2. {sunholo-0.62.13 → sunholo-0.62.15}/setup.py +1 -1
  3. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/flask/qna_routes.py +3 -4
  4. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/run_proxy.py +1 -1
  5. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/components/retriever.py +2 -2
  6. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/qna/parsers.py +1 -1
  7. sunholo-0.62.15/sunholo/vertex/__init__.py +3 -0
  8. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/vertex/memory_tools.py +56 -1
  9. sunholo-0.62.15/sunholo/vertex/safety.py +35 -0
  10. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo.egg-info/PKG-INFO +2 -2
  11. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo.egg-info/SOURCES.txt +1 -0
  12. {sunholo-0.62.13 → sunholo-0.62.15}/tests/test_dispatch_to_qa.py +5 -1
  13. sunholo-0.62.13/sunholo/vertex/__init__.py +0 -2
  14. {sunholo-0.62.13 → sunholo-0.62.15}/LICENSE.txt +0 -0
  15. {sunholo-0.62.13 → sunholo-0.62.15}/MANIFEST.in +0 -0
  16. {sunholo-0.62.13 → sunholo-0.62.15}/README.md +0 -0
  17. {sunholo-0.62.13 → sunholo-0.62.15}/setup.cfg +0 -0
  18. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/__init__.py +0 -0
  19. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/__init__.py +0 -0
  20. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/chat_history.py +0 -0
  21. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/dispatch_to_qa.py +0 -0
  22. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/fastapi/__init__.py +0 -0
  23. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/fastapi/base.py +0 -0
  24. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/fastapi/qna_routes.py +0 -0
  25. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/flask/__init__.py +0 -0
  26. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/flask/base.py +0 -0
  27. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/langserve.py +0 -0
  28. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/pubsub.py +0 -0
  29. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/route.py +0 -0
  30. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/agents/special_commands.py +0 -0
  31. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/archive/__init__.py +0 -0
  32. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/archive/archive.py +0 -0
  33. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/auth/__init__.py +0 -0
  34. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/auth/run.py +0 -0
  35. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/bots/__init__.py +0 -0
  36. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/bots/discord.py +0 -0
  37. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/bots/github_webhook.py +0 -0
  38. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/bots/webapp.py +0 -0
  39. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/__init__.py +0 -0
  40. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/data_to_embed_pubsub.py +0 -0
  41. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/doc_handling.py +0 -0
  42. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/images.py +0 -0
  43. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/loaders.py +0 -0
  44. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/message_data.py +0 -0
  45. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/pdfs.py +0 -0
  46. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/publish.py +0 -0
  47. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/chunker/splitter.py +0 -0
  48. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/__init__.py +0 -0
  49. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/chat_vac.py +0 -0
  50. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/cli.py +0 -0
  51. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/cli_init.py +0 -0
  52. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/configs.py +0 -0
  53. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/deploy.py +0 -0
  54. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/embedder.py +0 -0
  55. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/merge_texts.py +0 -0
  56. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/cli/sun_rich.py +0 -0
  57. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/components/__init__.py +0 -0
  58. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/components/llm.py +0 -0
  59. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/components/vectorstore.py +0 -0
  60. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/__init__.py +0 -0
  61. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/alloydb.py +0 -0
  62. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/database.py +0 -0
  63. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/lancedb.py +0 -0
  64. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/sql/sb/create_function.sql +0 -0
  65. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  66. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/sql/sb/create_table.sql +0 -0
  67. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  68. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/sql/sb/return_sources.sql +0 -0
  69. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/sql/sb/setup.sql +0 -0
  70. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/static_dbs.py +0 -0
  71. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/database/uuid.py +0 -0
  72. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/embedder/__init__.py +0 -0
  73. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/embedder/embed_chunk.py +0 -0
  74. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/gcs/__init__.py +0 -0
  75. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/gcs/add_file.py +0 -0
  76. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/gcs/download_url.py +0 -0
  77. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/gcs/metadata.py +0 -0
  78. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/langfuse/__init__.py +0 -0
  79. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/langfuse/callback.py +0 -0
  80. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/langfuse/prompts.py +0 -0
  81. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/llamaindex/__init__.py +0 -0
  82. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/llamaindex/generate.py +0 -0
  83. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/llamaindex/get_files.py +0 -0
  84. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/llamaindex/import_files.py +0 -0
  85. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/logging.py +0 -0
  86. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/lookup/__init__.py +0 -0
  87. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/lookup/model_lookup.yaml +0 -0
  88. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/patches/__init__.py +0 -0
  89. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/patches/langchain/__init__.py +0 -0
  90. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/patches/langchain/lancedb.py +0 -0
  91. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/patches/langchain/vertexai.py +0 -0
  92. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/pubsub/__init__.py +0 -0
  93. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/pubsub/process_pubsub.py +0 -0
  94. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/pubsub/pubsub_manager.py +0 -0
  95. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/qna/__init__.py +0 -0
  96. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/qna/retry.py +0 -0
  97. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/streaming/__init__.py +0 -0
  98. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/streaming/content_buffer.py +0 -0
  99. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/streaming/langserve.py +0 -0
  100. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/streaming/stream_lookup.py +0 -0
  101. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/streaming/streaming.py +0 -0
  102. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/summarise/__init__.py +0 -0
  103. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/summarise/summarise.py +0 -0
  104. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/__init__.py +0 -0
  105. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/big_context.py +0 -0
  106. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/config.py +0 -0
  107. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/config_schema.py +0 -0
  108. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/gcp.py +0 -0
  109. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/gcp_project.py +0 -0
  110. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/parsers.py +0 -0
  111. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/timedelta.py +0 -0
  112. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/utils/user_ids.py +0 -0
  113. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo/vertex/init.py +0 -0
  114. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo.egg-info/dependency_links.txt +0 -0
  115. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo.egg-info/entry_points.txt +0 -0
  116. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo.egg-info/requires.txt +0 -0
  117. {sunholo-0.62.13 → sunholo-0.62.15}/sunholo.egg-info/top_level.txt +0 -0
  118. {sunholo-0.62.13 → sunholo-0.62.15}/tests/test_chat_history.py +0 -0
  119. {sunholo-0.62.13 → sunholo-0.62.15}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.62.13
3
+ Version: 0.62.15
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.62.13.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.62.15.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.62.13'
4
+ version = '0.62.15'
5
5
 
6
6
  setup(
7
7
  name='sunholo',
@@ -45,7 +45,6 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
45
45
  return jsonify({"status": "healthy"})
46
46
 
47
47
  @app.route('/vac/streaming/<vector_name>', methods=['POST'])
48
- @observe()
49
48
  def stream_qa(vector_name):
50
49
  observed_stream_interpreter = observe()(stream_interpreter)
51
50
  prep = prep_vac(request, vector_name)
@@ -111,8 +110,8 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
111
110
  return response
112
111
 
113
112
  @app.route('/vac/<vector_name>', methods=['POST'])
114
- @observe()
115
113
  def process_qna(vector_name):
114
+ observed_vac_interpreter = observe()(vac_interpreter)
116
115
  prep = prep_vac(request, vector_name)
117
116
  log.debug(f"Processing prep: {prep}")
118
117
  trace = prep["trace"]
@@ -132,13 +131,13 @@ def register_qna_routes(app, stream_interpreter, vac_interpreter):
132
131
  input = all_input,
133
132
  model=vac_config.get("model") or vac_config.get("llm")
134
133
  )
135
- bot_output = vac_interpreter(
134
+ bot_output = observed_vac_interpreter(
136
135
  question=all_input["user_input"],
137
136
  vector_name=vector_name,
138
137
  chat_history=all_input["chat_history"],
139
138
  **all_input["kwargs"]
140
139
  )
141
- if generation:
140
+ if span:
142
141
  generation.end(output=bot_output)
143
142
  # {"answer": "The answer", "source_documents": [{"page_content": "The page content", "metadata": "The metadata"}]}
144
143
  bot_output = parse_output(bot_output)
@@ -277,7 +277,7 @@ def setup_proxy_subparser(subparsers):
277
277
  start_parser.add_argument('--port', type=int, help='Port to run the proxy on. Auto-assigns if not provided.')
278
278
  start_parser.add_argument('--local', action='store_true', help='Run the service locally instead of proxying to Cloud Run.')
279
279
  start_parser.add_argument('--app-type', choices=['flask', 'fastapi'], help='If local, type of the local app (flask or fastapi).')
280
- start_parser.add_argument('--app-folder', help='If local, folder containing the local app.py')
280
+ start_parser.add_argument('--app-folder', default=".", help='If local, folder containing the local app.py')
281
281
  start_parser.add_argument('--log-file', action='store_true', help='Whether to create a file containing proxy logs.')
282
282
  start_parser.set_defaults(func=lambda args: start_proxy(args.service_name,
283
283
  args.region,
@@ -29,7 +29,7 @@ from langchain.retrievers import ContextualCompressionRetriever
29
29
  def load_memories(vector_name):
30
30
  memories = load_config_key("memory", vector_name, kind="vacConfig")
31
31
  log.info(f"Found memory settings for {vector_name}: {memories}")
32
- if len(memories) == 0:
32
+ if not memories or len(memories) == 0:
33
33
  log.info(f"No memory settings found for {vector_name}")
34
34
  return None
35
35
 
@@ -67,7 +67,7 @@ def pick_retriever(vector_name, embeddings=None):
67
67
 
68
68
  #TODO: more memory stores here
69
69
 
70
- if len(retriever_list) == 0:
70
+ if not retriever_list or len(retriever_list) == 0:
71
71
  log.info(f"No retrievers were created for {memories}")
72
72
  return None
73
73
 
@@ -36,7 +36,7 @@ def parse_output(bot_output):
36
36
 
37
37
  return bot_output
38
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'):
39
+ elif isinstance(bot_output, dict) and 'metadata' in bot_output and isinstance(bot_output.get('metadata'), dict) and 'source_documents' in bot_output.get('metadata'):
40
40
  metadata = bot_output.get('metadata')
41
41
  bot_output['source_documents'] = [document_to_dict(doc) for doc in metadata['source_documents']]
42
42
  if not bot_output.get("answer") or bot_output.get("answer") == "":
@@ -0,0 +1,3 @@
1
+ from .init import init_vertex
2
+ from .memory_tools import get_vertex_memories, print_grounding_response
3
+ from .safety import vertex_safety
@@ -1,6 +1,6 @@
1
1
  try:
2
2
  from vertexai.preview import rag
3
- from vertexai.preview.generative_models import Tool, grounding
3
+ from vertexai.preview.generative_models import Tool, grounding, GenerationResponse
4
4
  except ImportError:
5
5
  rag = None
6
6
 
@@ -49,6 +49,10 @@ def get_vertex_memories(vector_name):
49
49
 
50
50
  memories = load_memories(vector_name)
51
51
  tools = []
52
+
53
+ if not memories:
54
+ return tools
55
+
52
56
  for memory in memories:
53
57
  for key, value in memory.items(): # Now iterate over the dictionary
54
58
  log.info(f"Found memory {key}")
@@ -89,3 +93,54 @@ def get_vertex_memories(vector_name):
89
93
  log.warning("No llamaindex Vertex corpus configurations could be found")
90
94
 
91
95
  return tools
96
+
97
+ def print_grounding_response(response):
98
+ """Prints Gemini response with grounding citations."""
99
+ grounding_metadata = response.candidates[0].grounding_metadata
100
+
101
+ # Citation indices are in byte units
102
+ ENCODING = "utf-8"
103
+ text_bytes = response.text.encode(ENCODING)
104
+
105
+ prev_index = 0
106
+ markdown_text = ""
107
+
108
+ sources: dict[str, str] = {}
109
+ footnote = 1
110
+ for attribution in grounding_metadata.grounding_attributions:
111
+ context = attribution.web or attribution.retrieved_context
112
+ if not context:
113
+ log.info(f"Skipping Grounding Attribution {attribution}")
114
+ continue
115
+
116
+ title = context.title
117
+ uri = context.uri
118
+ end_index = int(attribution.segment.end_index)
119
+
120
+ if uri not in sources:
121
+ sources[uri] = {"title": title, "footnote": footnote}
122
+ footnote += 1
123
+
124
+ text_segment = text_bytes[prev_index:end_index].decode(ENCODING)
125
+ markdown_text += f"{text_segment} [[{sources[uri]['footnote']}]]({uri})"
126
+ prev_index = end_index
127
+
128
+ if prev_index < len(text_bytes):
129
+ markdown_text += str(text_bytes[prev_index:], encoding=ENCODING)
130
+
131
+ markdown_text += "\n## Grounding Sources\n"
132
+
133
+ if grounding_metadata.web_search_queries:
134
+ markdown_text += (
135
+ f"\n**Web Search Queries:** {grounding_metadata.web_search_queries}\n"
136
+ )
137
+ elif grounding_metadata.retrieval_queries:
138
+ markdown_text += (
139
+ f"\n**Retrieval Queries:** {grounding_metadata.retrieval_queries}\n"
140
+ )
141
+
142
+ for uri, source in sources.items():
143
+ markdown_text += f"{source['footnote']}. [{source['title']}]({uri})\n"
144
+
145
+ log.info(markdown_text)
146
+ return markdown_text
@@ -0,0 +1,35 @@
1
+ try:
2
+ from vertexai.generative_models import (
3
+ HarmCategory,
4
+ HarmBlockThreshold,
5
+ )
6
+ except ImportError:
7
+ pass
8
+
9
+ def vertex_safety(threshold: str = "BLOCK_ONLY_HIGH"):
10
+ """
11
+ BLOCK_ONLY_HIGH - block when high probability of unsafe content is detected
12
+ BLOCK_MEDIUM_AND_ABOVE - block when medium or high probability of content is detected
13
+ BLOCK_LOW_AND_ABOVE - block when low, medium, or high probability of unsafe content is detected
14
+ BLOCK_NONE - no block, but need to be on an allow list to use
15
+ """
16
+
17
+ if threshold == 'BLOCK_ONLY_HIGH':
18
+ thresh = HarmBlockThreshold.BLOCK_ONLY_HIGH
19
+ elif threshold == 'BLOCK_MEDIUM_AND_ABOVE':
20
+ thresh = HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE
21
+ elif threshold == 'BLOCK_LOW_AND_ABOVE':
22
+ thresh = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE
23
+ elif threshold == 'BLOCK_NONE':
24
+ thresh = HarmBlockThreshold.BLOCK_NONE
25
+ else:
26
+ raise ValueError("Invalid threshold")
27
+
28
+ safety_settings = {
29
+ HarmCategory.HARM_CATEGORY_HARASSMENT: thresh,
30
+ HarmCategory.HARM_CATEGORY_HATE_SPEECH: thresh,
31
+ HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: thresh,
32
+ HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: thresh,
33
+ }
34
+
35
+ return safety_settings
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.62.13
3
+ Version: 0.62.15
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.62.13.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.62.15.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -111,6 +111,7 @@ sunholo/utils/user_ids.py
111
111
  sunholo/vertex/__init__.py
112
112
  sunholo/vertex/init.py
113
113
  sunholo/vertex/memory_tools.py
114
+ sunholo/vertex/safety.py
114
115
  tests/test_chat_history.py
115
116
  tests/test_config.py
116
117
  tests/test_dispatch_to_qa.py
@@ -4,7 +4,11 @@ from sunholo.agents.dispatch_to_qa import prep_request_payload
4
4
 
5
5
  @pytest.mark.parametrize("user_input, chat_history, vector_name, stream, expected_endpoint, expected_payload", [
6
6
  ("What is AI?", [], "my_vector", False, "http://example.com/invoke", {"user_input": "What is AI?", "chat_history": [], "vector_name": "my_vector"}),
7
- ("Tell me about ML", ["Previous chat message"], "another_vector", True, "http://example.com/stream", {"user_input": "Tell me about ML", "chat_history": ["Previous chat message"], "vector_name": "another_vector"})
7
+ ("Tell me about ML", ["Previous chat message"], "another_vector", True, "http://example.com/stream", {"user_input": "Tell me about ML", "chat_history": ["Previous chat message"], "vector_name": "another_vector"}),
8
+ # Additional test cases to cover all logic paths
9
+ ("", [], "empty_input_vector", False, "http://example.com/invoke", {"user_input": "", "chat_history": [], "vector_name": "empty_input_vector"}),
10
+ ("Valid input", ["Chat history present"], "history_vector", False, "http://example.com/invoke", {"user_input": "Valid input", "chat_history": ["Chat history present"], "vector_name": "history_vector"}),
11
+ ("Stream request", [], "stream_vector", True, "http://example.com/stream", {"user_input": "Stream request", "chat_history": [], "vector_name": "stream_vector"})
8
12
  ])
9
13
  @patch('sunholo.agents.dispatch_to_qa.load_config_key')
10
14
  @patch('sunholo.agents.dispatch_to_qa.route_endpoint')
@@ -1,2 +0,0 @@
1
- from .init import init_vertex
2
- from .memory_tools import get_vertex_memories
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes