sunholo 0.62.17__py3-none-any.whl → 0.63.0__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/run.py +19 -22
- sunholo/cli/chat_vac.py +72 -37
- sunholo/cli/embedder.py +16 -7
- {sunholo-0.62.17.dist-info → sunholo-0.63.0.dist-info}/METADATA +9 -42
- {sunholo-0.62.17.dist-info → sunholo-0.63.0.dist-info}/RECORD +9 -9
- {sunholo-0.62.17.dist-info → sunholo-0.63.0.dist-info}/LICENSE.txt +0 -0
- {sunholo-0.62.17.dist-info → sunholo-0.63.0.dist-info}/WHEEL +0 -0
- {sunholo-0.62.17.dist-info → sunholo-0.63.0.dist-info}/entry_points.txt +0 -0
- {sunholo-0.62.17.dist-info → sunholo-0.63.0.dist-info}/top_level.txt +0 -0
sunholo/auth/run.py
CHANGED
|
@@ -53,26 +53,23 @@ def get_header(vector_name) -> Optional[dict]:
|
|
|
53
53
|
else:
|
|
54
54
|
run_url = "http://127.0.0.1:8080"
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
else
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
# Append ID Token to make authenticated requests to Cloud Run services
|
|
57
|
+
frame = inspect.currentframe()
|
|
58
|
+
caller_frame = frame.f_back if frame is not None else None # One level up in the stack
|
|
59
|
+
deets = {
|
|
60
|
+
'message': 'Authenticating for run_url',
|
|
61
|
+
'run_url': run_url
|
|
62
|
+
}
|
|
63
|
+
if caller_frame:
|
|
62
64
|
deets = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
log.info(f"Authenticating for run_url {run_url} from {caller_frame.f_code.co_name}")
|
|
75
|
-
id_token = get_id_token(run_url)
|
|
76
|
-
headers = {"Authorization": f"Bearer {id_token}"}
|
|
77
|
-
#log.info(f"id_token {id_token}")
|
|
78
|
-
return headers
|
|
65
|
+
'message': 'Authenticating for run_url',
|
|
66
|
+
'file': caller_frame.f_code.co_filename,
|
|
67
|
+
'line': str(caller_frame.f_lineno),
|
|
68
|
+
'function': caller_frame.f_code.co_name,
|
|
69
|
+
'run_url': run_url
|
|
70
|
+
}
|
|
71
|
+
log.info(f"Authenticating for run_url {run_url} from {caller_frame.f_code.co_name}")
|
|
72
|
+
id_token = get_id_token(run_url)
|
|
73
|
+
headers = {"Authorization": f"Bearer {id_token}"}
|
|
74
|
+
#log.info(f"id_token {id_token}")
|
|
75
|
+
return headers
|
sunholo/cli/chat_vac.py
CHANGED
|
@@ -149,46 +149,72 @@ def headless_mode(service_url, service_name, user_input, chat_history=None, stre
|
|
|
149
149
|
user_id = generate_user_id()
|
|
150
150
|
session_id = str(uuid.uuid4())
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
152
|
+
if not stream:
|
|
153
|
+
vac_response = send_to_qa(user_input,
|
|
154
|
+
vector_name=service_name,
|
|
155
|
+
chat_history=chat_history,
|
|
156
|
+
message_author=user_id,
|
|
157
|
+
#TODO: populate these
|
|
158
|
+
image_url=None,
|
|
159
|
+
source_filters=None,
|
|
160
|
+
search_kwargs=None,
|
|
161
|
+
private_docs=None,
|
|
162
|
+
whole_document=False,
|
|
163
|
+
source_filters_and_or=False,
|
|
164
|
+
# system kwargs
|
|
165
|
+
configurable={
|
|
166
|
+
"vector_name": service_name,
|
|
167
|
+
},
|
|
168
|
+
user_id=user_id,
|
|
169
|
+
session_id=session_id,
|
|
170
|
+
message_source="cli",
|
|
171
|
+
override_endpoint=service_url)
|
|
172
|
+
|
|
173
|
+
# ensures {'answer': answer}
|
|
174
|
+
answer = parse_output(vac_response)
|
|
175
|
+
|
|
176
|
+
console.print(answer.get('answer'))
|
|
177
|
+
else:
|
|
178
|
+
def stream_response():
|
|
179
|
+
generate = generate_proxy_stream(
|
|
180
|
+
send_to_qa,
|
|
181
|
+
user_input,
|
|
182
|
+
vector_name=service_name,
|
|
183
|
+
chat_history=chat_history,
|
|
184
|
+
generate_f_output=lambda x: x, # Replace with actual processing function
|
|
185
|
+
stream_wait_time=0.5,
|
|
186
|
+
stream_timeout=120,
|
|
187
|
+
message_author=user_id,
|
|
188
|
+
#TODO: populate these
|
|
189
|
+
image_url=None,
|
|
190
|
+
source_filters=None,
|
|
191
|
+
search_kwargs=None,
|
|
192
|
+
private_docs=None,
|
|
193
|
+
whole_document=False,
|
|
194
|
+
source_filters_and_or=False,
|
|
195
|
+
# system kwargs
|
|
196
|
+
configurable={
|
|
197
|
+
"vector_name": service_name,
|
|
198
|
+
},
|
|
199
|
+
user_id=user_id,
|
|
200
|
+
session_id=session_id,
|
|
201
|
+
message_source="cli",
|
|
202
|
+
override_endpoint=service_url
|
|
203
|
+
)
|
|
204
|
+
for part in generate():
|
|
205
|
+
yield part
|
|
180
206
|
|
|
181
|
-
|
|
207
|
+
answer = ""
|
|
182
208
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
209
|
+
for token in stream_response():
|
|
210
|
+
if isinstance(token, bytes):
|
|
211
|
+
token = token.decode('utf-8')
|
|
212
|
+
print(token, end='', flush=True)
|
|
213
|
+
answer += token
|
|
188
214
|
|
|
189
|
-
if
|
|
215
|
+
if answer:
|
|
190
216
|
chat_history.append({"name": "Human", "content": user_input})
|
|
191
|
-
chat_history.append({"name": "AI", "content":
|
|
217
|
+
chat_history.append({"name": "AI", "content": answer})
|
|
192
218
|
print() # For new line after streaming ends
|
|
193
219
|
|
|
194
220
|
return chat_history
|
|
@@ -273,6 +299,7 @@ def vac_command(args):
|
|
|
273
299
|
def invoke_vac(service_url, data, vector_name=None, metadata=None, is_file=False):
|
|
274
300
|
try:
|
|
275
301
|
if is_file:
|
|
302
|
+
console.print("Uploading file to chunker...")
|
|
276
303
|
# Handle file upload
|
|
277
304
|
if not isinstance(data, Path) or not data.is_file():
|
|
278
305
|
raise ValueError("For file uploads, 'data' must be a Path object pointing to a valid file.")
|
|
@@ -287,12 +314,20 @@ def invoke_vac(service_url, data, vector_name=None, metadata=None, is_file=False
|
|
|
287
314
|
|
|
288
315
|
response = requests.post(service_url, files=files, data=form_data)
|
|
289
316
|
else:
|
|
317
|
+
console.print("Uploading JSON to chunker...")
|
|
290
318
|
try:
|
|
291
|
-
|
|
319
|
+
if isinstance(data, dict):
|
|
320
|
+
json_data = data
|
|
321
|
+
else:
|
|
322
|
+
json_data = json.loads(data)
|
|
292
323
|
except json.JSONDecodeError as err:
|
|
293
324
|
console.print(f"[bold red]ERROR: invalid JSON: {str(err)} [/bold red]")
|
|
294
325
|
sys.exit(1)
|
|
326
|
+
except Exception as err:
|
|
327
|
+
console.print(f"[bold red]ERROR: could not parse JSON: {str(err)} [/bold red]")
|
|
328
|
+
sys.exit(1)
|
|
295
329
|
|
|
330
|
+
log.debug(f"Sending data: {data} or json_data: {json.dumps(json_data)}")
|
|
296
331
|
# Handle JSON data
|
|
297
332
|
headers = {"Content-Type": "application/json"}
|
|
298
333
|
response = requests.post(service_url, headers=headers, data=json.dumps(json_data))
|
sunholo/cli/embedder.py
CHANGED
|
@@ -18,12 +18,15 @@ def create_metadata(vac, metadata):
|
|
|
18
18
|
# Default metadata if none provided
|
|
19
19
|
default_metadata = {"vector_name": vac, "source": "sunholo-cli", "eventTime": formatted_time}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
try:
|
|
22
|
+
# Merge default metadata with provided metadata
|
|
23
|
+
if metadata:
|
|
24
|
+
if not isinstance(metadata, dict):
|
|
25
|
+
metadata = json.loads(metadata)
|
|
26
|
+
else:
|
|
27
|
+
metadata = {}
|
|
28
|
+
except Exception as err:
|
|
29
|
+
console.print(f"[bold red]ERROR: metadata not parsed: {err} for {metadata}")
|
|
27
30
|
|
|
28
31
|
# Update metadata with default values if not present
|
|
29
32
|
metadata.update(default_metadata)
|
|
@@ -87,7 +90,7 @@ def embed_command(args):
|
|
|
87
90
|
chunk_args = Namespace(**chunk_args)
|
|
88
91
|
chunk_url = resolve_service_url(chunk_args, no_config=True)
|
|
89
92
|
|
|
90
|
-
with console.status(f"[bold orange]Sending {args.data} to chunk via {chunk_url}[/bold orange]", spinner="star"):
|
|
93
|
+
with console.status(f"[bold orange]Sending '{args.data}' to chunk via {chunk_url}[/bold orange]", spinner="star"):
|
|
91
94
|
if args.is_file:
|
|
92
95
|
|
|
93
96
|
metadata = create_metadata(args.vac_name, args.metadata)
|
|
@@ -102,6 +105,7 @@ def embed_command(args):
|
|
|
102
105
|
|
|
103
106
|
else:
|
|
104
107
|
json_data = encode_data(args.vac_name, args.data, args.metadata, args.local_chunks)
|
|
108
|
+
console.print(f"Chunk JSON data: {json_data}")
|
|
105
109
|
chunk_res = invoke_vac(f"{chunk_url}/pubsub_to_store", json_data)
|
|
106
110
|
|
|
107
111
|
stop_proxy("chunker")
|
|
@@ -113,6 +117,11 @@ def embed_command(args):
|
|
|
113
117
|
|
|
114
118
|
return
|
|
115
119
|
|
|
120
|
+
if not chunk_res:
|
|
121
|
+
console.rule(f"[bold orange]No chunks were found for processing of {args.data}[/bold orange]")
|
|
122
|
+
|
|
123
|
+
return
|
|
124
|
+
|
|
116
125
|
console.rule("Processing chunks locally")
|
|
117
126
|
|
|
118
127
|
if args.embed_override:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.63.0
|
|
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.63.0.tar.gz
|
|
7
7
|
Author: Holosun ApS
|
|
8
8
|
Author-email: multivac@sunholo.com
|
|
9
9
|
License: Apache License, Version 2.0
|
|
@@ -111,54 +111,21 @@ This is the Sunholo Python project, a comprehensive toolkit for working with lan
|
|
|
111
111
|
|
|
112
112
|
Please refer to the website for full documentation at https://dev.sunholo.com/
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
(draft release https://pypi.org/project/sunholo/ )
|
|
117
|
-
## Table of Contents
|
|
118
|
-
- [Agents](#agents)
|
|
119
|
-
- [Archive](#archive)
|
|
120
|
-
- [Bots](#bots)
|
|
121
|
-
- [Chunker](#chunker)
|
|
122
|
-
- [Components](#components)
|
|
123
|
-
- [Database](#database)
|
|
124
|
-
- [Embedder](#embedder)
|
|
125
|
-
- [PubSub](#pubsub)
|
|
126
|
-
- [QnA](#qna)
|
|
127
|
-
- [Streaming](#streaming)
|
|
128
|
-
- [Summarise](#summarise)
|
|
129
|
-
- [Utils](#utils)
|
|
114
|
+
## Demos
|
|
130
115
|
|
|
116
|
+
Using https://github.com/charmbracelet/vhs
|
|
131
117
|
|
|
132
118
|
```sh
|
|
133
|
-
|
|
119
|
+
vhs record > cassette.tape
|
|
134
120
|
```
|
|
135
121
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
`sunholo` provides utilities to help manage LLM operations on Google Cloud Platform at first, but it is hoped that making it open source will help it support other clouds in the future. A lot of the functionality is not Google Cloud Platform specific, so still may be helpful.
|
|
139
|
-
|
|
140
|
-
It is derived from the Edmonbrain project, the original blog post you can read here: https://code.markedmondson.me/running-llms-on-gcp/ and owes a lot to Langchain ( https://github.com/langchain-ai/langchain )
|
|
141
|
-
|
|
142
|
-
The package includes:
|
|
122
|
+
Then make gif:
|
|
143
123
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
* `chunker/` - functions to slice up documents for sending into vector stores
|
|
148
|
-
* `components/` - functions to help configure which LLM, prompt, vectorstore or document retriever you will use based on a yaml config file
|
|
149
|
-
* `database/` - database setup functions and SQL to run on those sources such as Supabase
|
|
150
|
-
* `embedder/` - functions to send chunks into embedding vector stores
|
|
151
|
-
* `pubsub/` - use of PubSub for a message queue between components
|
|
152
|
-
* `qna/` - utilities for running agents such as retry strats and parsing of output/input
|
|
153
|
-
* `streaming/` - creation of streaming responses from LLM bots
|
|
154
|
-
* `summarise/` - creation of summaries of large documents
|
|
155
|
-
* `utils/` - reading configuration files, Google Cloud Platform metadata
|
|
156
|
-
|
|
157
|
-
## Configuration
|
|
124
|
+
```sh
|
|
125
|
+
vhs docs/tapes/config-list.tape
|
|
126
|
+
```
|
|
158
127
|
|
|
159
|
-
The library uses the config specifications that some examples are given in the `config/` folder.
|
|
160
128
|
|
|
161
|
-
When using the functions, make sure to have the `config/` folder in the root of where your application is running (usually `$HOME/config`)
|
|
162
129
|
|
|
163
130
|
```
|
|
164
131
|
Copyright [2024] [Holosun ApS]
|
|
@@ -16,7 +16,7 @@ sunholo/agents/flask/qna_routes.py,sha256=Twx6bitUAQ8Urtuwu9PtdoxYv-3aBDbF4cOUl9
|
|
|
16
16
|
sunholo/archive/__init__.py,sha256=qNHWm5rGPVOlxZBZCpA1wTYPbalizRT7f8X4rs2t290,31
|
|
17
17
|
sunholo/archive/archive.py,sha256=C-UhG5x-XtZ8VheQp92IYJqgD0V3NFQjniqlit94t18,1197
|
|
18
18
|
sunholo/auth/__init__.py,sha256=4owDjSaWYkbTlPK47UHTOC0gCWbZsqn4ZIEw5NWZTlg,28
|
|
19
|
-
sunholo/auth/run.py,sha256=
|
|
19
|
+
sunholo/auth/run.py,sha256=SoXkyRSSO3ln4Uq71Zj2J2P9_TRp0Pg_wU1D9kI24Io,2690
|
|
20
20
|
sunholo/bots/__init__.py,sha256=EMFd7e2z68l6pzYOnkzHbLd2xJRvxTKFRNCTuhZ8hIw,130
|
|
21
21
|
sunholo/bots/discord.py,sha256=cCFae5K1BCa6JVkWGLh_iZ9qFO1JpXb6K4eJrlDfEro,2442
|
|
22
22
|
sunholo/bots/github_webhook.py,sha256=5pQPRLM_wxxcILVaIzUDV8Kt7Arcm2dL1r1kMMHA524,9629
|
|
@@ -31,12 +31,12 @@ sunholo/chunker/pdfs.py,sha256=daCZ1xjn1YvxlifIyxskWNpLJLe-Q9D_Jq12MWx3tZo,2473
|
|
|
31
31
|
sunholo/chunker/publish.py,sha256=GNXV6IPdKM2GZUcjGXIERu49D0ITYtizsLIktKVtMjM,2768
|
|
32
32
|
sunholo/chunker/splitter.py,sha256=FLkDhkePkg_zGQpFBK13Cznw575D-Rf9pcaCpc1HUxY,6726
|
|
33
33
|
sunholo/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
-
sunholo/cli/chat_vac.py,sha256=
|
|
34
|
+
sunholo/cli/chat_vac.py,sha256=RbhKICZtWZEPwL9wFmTNzhCWKHHRmNSqQHIfA-wi04U,17820
|
|
35
35
|
sunholo/cli/cli.py,sha256=1-grjOE5sB5k0wrccsqCWSXB1vfrYNgdHBFH5F94pa0,3632
|
|
36
36
|
sunholo/cli/cli_init.py,sha256=JMZ9AX2cPDZ-_mv3adiv2ToFVNyRPtjk9Biszl1kiR0,2358
|
|
37
37
|
sunholo/cli/configs.py,sha256=QUM9DvKOdZmEQRM5uI3Nh887T0YDiSMr7O240zTLqws,4546
|
|
38
38
|
sunholo/cli/deploy.py,sha256=zxdwUsRTRMC8U5vyRv0JiKBLFn84Ug_Tc88-_h9hJSs,1609
|
|
39
|
-
sunholo/cli/embedder.py,sha256=
|
|
39
|
+
sunholo/cli/embedder.py,sha256=w7LT1CANSoQbOz8xAP3Zt4C_hP4lzGJOf8XD2jY5jBQ,7291
|
|
40
40
|
sunholo/cli/merge_texts.py,sha256=U9vdMwKmcPoc6iPOWX5MKSxn49dNGbNzVLw8ui5PhEU,1823
|
|
41
41
|
sunholo/cli/run_proxy.py,sha256=8mrZj0GPYO1q5e6cxej-PHdns5pGguWoDrX7RFg0FWo,11581
|
|
42
42
|
sunholo/cli/sun_rich.py,sha256=UpMqeJ0C8i0pkue1AHnnyyX0bFJ9zZeJ7HBR6yhuA8A,54
|
|
@@ -101,9 +101,9 @@ sunholo/vertex/__init__.py,sha256=JvHcGFuv6R_nAhY2AdoqqhMpJ5ugeWPZ_svGhWrObBk,13
|
|
|
101
101
|
sunholo/vertex/init.py,sha256=JDMUaBRdednzbKF-5p33qqLit2LMsvgvWW-NRz0AqO0,1801
|
|
102
102
|
sunholo/vertex/memory_tools.py,sha256=8F1iTWnqEK9mX4W5RzCVKIjydIcNp6OFxjn_dtQ3GXo,5379
|
|
103
103
|
sunholo/vertex/safety.py,sha256=3meAX0HyGZYrH7rXPUAHxtI_3w_zoy_RX7Shtkoa660,1275
|
|
104
|
-
sunholo-0.
|
|
105
|
-
sunholo-0.
|
|
106
|
-
sunholo-0.
|
|
107
|
-
sunholo-0.
|
|
108
|
-
sunholo-0.
|
|
109
|
-
sunholo-0.
|
|
104
|
+
sunholo-0.63.0.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
|
|
105
|
+
sunholo-0.63.0.dist-info/METADATA,sha256=0jHRQDDREVfY0MVPf6CZe6wZ_kiSePMGUg5li128Yf8,5939
|
|
106
|
+
sunholo-0.63.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
107
|
+
sunholo-0.63.0.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
|
|
108
|
+
sunholo-0.63.0.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
|
|
109
|
+
sunholo-0.63.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|