llumo 0.1.8__py3-none-any.whl → 0.1.9b10__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.
- llumo/client.py +230 -9
- llumo/exceptions.py +9 -3
- llumo/helpingFuntions.py +87 -0
- llumo-0.1.9b10.dist-info/METADATA +17 -0
- llumo-0.1.9b10.dist-info/RECORD +13 -0
- {llumo-0.1.8.dist-info → llumo-0.1.9b10.dist-info}/WHEEL +1 -1
- llumo-0.1.8.dist-info/METADATA +0 -26
- llumo-0.1.8.dist-info/RECORD +0 -13
- {llumo-0.1.8.dist-info → llumo-0.1.9b10.dist-info}/licenses/LICENSE +0 -0
- {llumo-0.1.8.dist-info → llumo-0.1.9b10.dist-info}/top_level.txt +0 -0
llumo/client.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import requests
|
2
|
+
from docutils.nodes import subscript
|
3
|
+
|
2
4
|
from .exceptions import LlumoAIError
|
3
5
|
import time
|
4
6
|
import re
|
5
7
|
import json
|
6
8
|
import uuid
|
7
9
|
import threading
|
8
|
-
from .helpingFuntions import *
|
9
10
|
from dotenv import load_dotenv
|
10
11
|
import os
|
11
12
|
import itertools
|
@@ -13,6 +14,7 @@ import pandas as pd
|
|
13
14
|
from typing import List, Dict
|
14
15
|
from .models import AVAILABLEMODELS,getProviderFromModel
|
15
16
|
from .execution import ModelExecutor
|
17
|
+
from .helpingFuntions import *
|
16
18
|
from .sockets import LlumoSocketClient
|
17
19
|
from .functionCalling import LlumoAgentExecutor
|
18
20
|
|
@@ -21,9 +23,9 @@ from .functionCalling import LlumoAgentExecutor
|
|
21
23
|
envPath = os.path.join(os.path.dirname(__file__), '.env')
|
22
24
|
load_dotenv(dotenv_path=envPath, override=False)# Automatically looks for .env in current directory
|
23
25
|
|
24
|
-
postUrl = os.getenv("
|
25
|
-
fetchUrl = os.getenv("
|
26
|
-
validateUrl = os.getenv("
|
26
|
+
postUrl = os.getenv("POST_URL")
|
27
|
+
fetchUrl = os.getenv("FETCH_URL")
|
28
|
+
validateUrl = os.getenv("VALIDATE_URL")
|
27
29
|
socketUrl = os.getenv("SOCKET_URL")
|
28
30
|
|
29
31
|
|
@@ -33,6 +35,7 @@ class LlumoClient:
|
|
33
35
|
self.apiKey = api_key
|
34
36
|
self.socket = LlumoSocketClient(socketUrl)
|
35
37
|
self.processMapping = {}
|
38
|
+
|
36
39
|
|
37
40
|
|
38
41
|
def validateApiKey(self, evalName = ""):
|
@@ -99,6 +102,9 @@ class LlumoClient:
|
|
99
102
|
self.workspaceID = data["data"].get("workspaceID")
|
100
103
|
self.evalDefinition = data["data"].get("analyticsMapping")
|
101
104
|
self.socketToken = data["data"].get("token")
|
105
|
+
self.hasSubscribed = data["data"].get("hasSubscribed",False)
|
106
|
+
self.trialEndDate = data["data"].get("trialEndDate",None)
|
107
|
+
self.subscriptionEndDate = data["data"].get("subscriptionEndDate", None)
|
102
108
|
|
103
109
|
# print(f"API key validation successful:")
|
104
110
|
# print(f"- Remaining hits: {self.hitsAvailable}")
|
@@ -115,6 +121,7 @@ class LlumoClient:
|
|
115
121
|
"runType": "EVAL",
|
116
122
|
"workspaceID": workspaceID,
|
117
123
|
}
|
124
|
+
# socketToken here if the "JWD" token
|
118
125
|
headers = {
|
119
126
|
"Authorization": f"Bearer {self.socketToken}",
|
120
127
|
"Content-Type": "application/json",
|
@@ -127,6 +134,28 @@ class LlumoClient:
|
|
127
134
|
|
128
135
|
except Exception as e:
|
129
136
|
print(f"Error in posting batch: {e}")
|
137
|
+
|
138
|
+
|
139
|
+
def postDataStream(self, batch, workspaceID):
|
140
|
+
payload = {
|
141
|
+
"batch": json.dumps(batch),
|
142
|
+
"runType": "DATA_STREAM",
|
143
|
+
"workspaceID": workspaceID,
|
144
|
+
}
|
145
|
+
# socketToken here if the "JWD" token
|
146
|
+
headers = {
|
147
|
+
"Authorization": f"Bearer {self.socketToken}",
|
148
|
+
"Content-Type": "application/json",
|
149
|
+
}
|
150
|
+
try:
|
151
|
+
# print(postUrl)
|
152
|
+
response = requests.post(postUrl, json=payload, headers=headers)
|
153
|
+
# print(f"Post API Status Code: {response.status_code}")
|
154
|
+
# print(response.text)
|
155
|
+
|
156
|
+
except Exception as e:
|
157
|
+
print(f"Error in posting batch: {e}")
|
158
|
+
|
130
159
|
|
131
160
|
def AllProcessMapping(self):
|
132
161
|
for batch in self.allBatches:
|
@@ -143,6 +172,7 @@ class LlumoClient:
|
|
143
172
|
|
144
173
|
for item in results:
|
145
174
|
for rowID in item: # Each item has only one key
|
175
|
+
# for rowID in item["data"]:
|
146
176
|
if rowID not in seen:
|
147
177
|
seen.add(rowID)
|
148
178
|
uniqueResults.append(item)
|
@@ -175,9 +205,14 @@ class LlumoClient:
|
|
175
205
|
if hasattr(e, "response") and getattr(e, "response", None) is not None:
|
176
206
|
pass
|
177
207
|
raise
|
208
|
+
userHits = checkUserHits(self.workspaceID,self.hasSubscribed,self.trialEndDate,self.subscriptionEndDate,self.hitsAvailable,len(dataframe))
|
209
|
+
|
178
210
|
|
179
|
-
if
|
180
|
-
raise LlumoAIError.InsufficientCredits()
|
211
|
+
if not userHits["success"]:
|
212
|
+
raise LlumoAIError.InsufficientCredits(userHits["message"])
|
213
|
+
|
214
|
+
# if self.hitsAvailable == 0 or len(dataframe) > self.hitsAvailable:
|
215
|
+
# raise LlumoAIError.InsufficientCredits()
|
181
216
|
|
182
217
|
evalDefinition = self.evalDefinition[eval]
|
183
218
|
model = "GPT_4"
|
@@ -206,6 +241,7 @@ class LlumoClient:
|
|
206
241
|
rowID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
207
242
|
columnID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
208
243
|
|
244
|
+
# storing the generated rowID and the row index (dataframe) for later lookkup
|
209
245
|
rowIdMapping[rowID] = index
|
210
246
|
|
211
247
|
templateData = {
|
@@ -298,10 +334,17 @@ class LlumoClient:
|
|
298
334
|
dataframe[evalName] = None
|
299
335
|
for item in records:
|
300
336
|
for compound_key, value in item.items():
|
337
|
+
# for compound_key, value in item['data'].items():
|
338
|
+
|
301
339
|
rowID = compound_key.split('-')[0]
|
340
|
+
# looking for the index of each rowID , in the original dataframe
|
302
341
|
if rowID in rowIdMapping:
|
303
342
|
index = rowIdMapping[rowID]
|
304
|
-
dataframe.at[index, evalName] = value
|
343
|
+
# dataframe.at[index, evalName] = value
|
344
|
+
dataframe.at[index, evalName] = value["value"]
|
345
|
+
dataframe.at[index, f'{evalName} Reason'] = value["reasoning"]
|
346
|
+
|
347
|
+
|
305
348
|
else:
|
306
349
|
pass
|
307
350
|
# print(f"⚠️ Warning: Could not find rowID {rowID} in mapping")
|
@@ -338,8 +381,16 @@ class LlumoClient:
|
|
338
381
|
print(f"Response content: {e.response.text[:500]}...")
|
339
382
|
raise
|
340
383
|
|
341
|
-
|
342
|
-
|
384
|
+
# check for available hits and trial limit
|
385
|
+
userHits = checkUserHits(self.workspaceID, self.hasSubscribed, self.trialEndDate, self.subscriptionEndDate,
|
386
|
+
self.hitsAvailable, len(dataframe))
|
387
|
+
|
388
|
+
# do not proceed if subscription or trial limit has exhausted
|
389
|
+
if not userHits["success"]:
|
390
|
+
raise LlumoAIError.InsufficientCredits(userHits["message"])
|
391
|
+
|
392
|
+
# if self.hitsAvailable == 0 or len(dataframe) > self.hitsAvailable:
|
393
|
+
# raise LlumoAIError.InsufficientCredits()
|
343
394
|
|
344
395
|
model = "GPT_4"
|
345
396
|
provider = "OPENAI"
|
@@ -555,7 +606,177 @@ class LlumoClient:
|
|
555
606
|
)
|
556
607
|
return toolResponseDf
|
557
608
|
|
609
|
+
def evaluateAgentResponses(self, dataframe, prompt_template="Give answer for the given query: {{query}}"):
|
610
|
+
try:
|
611
|
+
if "query" and "messageHistory" and "tools" not in dataframe.columns:
|
612
|
+
raise ValueError("DataFrame must contain 'query', 'messageHistory', and 'tools' columns")
|
613
|
+
evals = ["Tool Reliability", "Stepwise Progression", "Tool Selection Accuracy", "Final Task Alignment"]
|
614
|
+
toolResponseDf = dataframe.copy()
|
615
|
+
for eval in evals:
|
616
|
+
# Perform evaluation
|
617
|
+
toolResponseDf = self.evaluate(
|
618
|
+
toolResponseDf,
|
619
|
+
eval = eval,
|
620
|
+
prompt_template=prompt_template
|
621
|
+
)
|
622
|
+
return toolResponseDf
|
623
|
+
|
624
|
+
except Exception as e:
|
625
|
+
raise e
|
626
|
+
|
627
|
+
def runDataStream(self, dataframe, streamName:str,queryColName:str="query"):
|
628
|
+
results = {}
|
629
|
+
|
630
|
+
try:
|
631
|
+
socketID = self.socket.connect(timeout=150)
|
632
|
+
# Ensure full connection before proceeding
|
633
|
+
max_wait_secs = 20
|
634
|
+
waited_secs = 0
|
635
|
+
while not self.socket._connection_established.is_set():
|
636
|
+
time.sleep(0.1)
|
637
|
+
waited_secs += 0.1
|
638
|
+
if waited_secs >= max_wait_secs:
|
639
|
+
raise RuntimeError("Timeout waiting for server 'connection-established' event.")
|
640
|
+
# print(f"Connected with socket ID: {socketID}")
|
641
|
+
rowIdMapping = {}
|
642
|
+
try:
|
643
|
+
# print(f"Validating API key...")
|
644
|
+
self.validateApiKey()
|
645
|
+
# print(f"API key validation successful. Hits available: {self.hitsAvailable}")
|
646
|
+
except Exception as e:
|
647
|
+
print(f"Error during API key validation: {str(e)}")
|
648
|
+
if hasattr(e, "response") and getattr(e, "response", None) is not None:
|
649
|
+
print(f"Status code: {e.response.status_code}")
|
650
|
+
print(f"Response content: {e.response.text[:500]}...")
|
651
|
+
raise
|
652
|
+
# check for available hits and trial limit
|
653
|
+
userHits = checkUserHits(self.workspaceID, self.hasSubscribed, self.trialEndDate, self.subscriptionEndDate,
|
654
|
+
self.hitsAvailable, len(dataframe))
|
655
|
+
|
656
|
+
# do not proceed if subscription or trial limit has exhausted
|
657
|
+
if not userHits["success"]:
|
658
|
+
raise LlumoAIError.InsufficientCredits(userHits["message"])
|
659
|
+
|
660
|
+
|
558
661
|
|
662
|
+
print("====🚀Sit back while we fetch data from the stream 🚀====")
|
663
|
+
workspaceID = self.workspaceID
|
664
|
+
streamId=getStreamId(workspaceID,self.apiKey,streamName)
|
665
|
+
# Prepare all batches before sending
|
666
|
+
# print("Preparing batches...")
|
667
|
+
self.allBatches = []
|
668
|
+
currentBatch = []
|
669
|
+
|
670
|
+
for index, row in dataframe.iterrows():
|
671
|
+
activePlayground = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
672
|
+
rowID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
673
|
+
columnID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
|
674
|
+
|
675
|
+
rowIdMapping[rowID] = index
|
676
|
+
# Use the server-provided socket ID here
|
677
|
+
templateData = {
|
678
|
+
"processID": getProcessID(),
|
679
|
+
"socketID": socketID,
|
680
|
+
"processData": {
|
681
|
+
"executionDependency": {
|
682
|
+
"query": row[queryColName]
|
683
|
+
},
|
684
|
+
"dataStreamID": streamId
|
685
|
+
},
|
686
|
+
"workspaceID": workspaceID,
|
687
|
+
"email": "",
|
688
|
+
"type": "DATA_STREAM",
|
689
|
+
"playgroundID": activePlayground,
|
690
|
+
"processType": "DATA_STREAM",
|
691
|
+
"rowID": rowID,
|
692
|
+
"columnID": columnID,
|
693
|
+
"source": "SDK"
|
694
|
+
|
695
|
+
}
|
696
|
+
|
697
|
+
|
698
|
+
currentBatch.append(templateData)
|
699
|
+
|
700
|
+
if len(currentBatch) == 10 or index == len(dataframe) - 1:
|
701
|
+
self.allBatches.append(currentBatch)
|
702
|
+
currentBatch = []
|
703
|
+
|
704
|
+
# Post all batches
|
705
|
+
total_items = sum(len(batch) for batch in self.allBatches)
|
706
|
+
# print(f"Posting {len(self.allBatches)} batches ({total_items} items total)")
|
707
|
+
|
708
|
+
for cnt, batch in enumerate(self.allBatches):
|
709
|
+
# print(f"Posting batch {cnt + 1}/{len(self.allBatches)} for eval '{eval}'")
|
710
|
+
try:
|
711
|
+
self.postDataStream(batch=batch, workspaceID=workspaceID)
|
712
|
+
# print(f"Batch {cnt + 1} posted successfully")
|
713
|
+
except Exception as e:
|
714
|
+
print(f"Error posting batch {cnt + 1}: {str(e)}")
|
715
|
+
continue
|
716
|
+
|
717
|
+
# Small delay between batches to prevent overwhelming the server
|
718
|
+
time.sleep(1)
|
719
|
+
|
720
|
+
# updating the dict for row column mapping
|
721
|
+
self.AllProcessMapping()
|
722
|
+
# Calculate a reasonable timeout based on the data size
|
723
|
+
timeout = max(60, min(600, total_items * 10))
|
724
|
+
# print(f"All batches posted. Waiting up to {timeout} seconds for results...")
|
725
|
+
|
726
|
+
# Listen for results
|
727
|
+
self.socket.listenForResults(min_wait=20, max_wait=timeout, inactivity_timeout=30,expected_results=None)
|
728
|
+
|
729
|
+
# Get results for this evaluation
|
730
|
+
eval_results = self.socket.getReceivedData()
|
731
|
+
# print(f"Received {len(eval_results)} results for evaluation '{eval}'")
|
732
|
+
|
733
|
+
# Add these results to our overall results
|
734
|
+
results["Data Stream"] = self.finalResp(eval_results)
|
735
|
+
print(f"=======You are all set! continue your expectations 🚀======\n")
|
736
|
+
|
737
|
+
|
738
|
+
# print("All evaluations completed successfully")
|
739
|
+
|
740
|
+
except Exception as e:
|
741
|
+
print(f"Error during evaluation: {e}")
|
742
|
+
raise
|
743
|
+
finally:
|
744
|
+
# Always disconnect the socket when done
|
745
|
+
try:
|
746
|
+
self.socket.disconnect()
|
747
|
+
# print("Socket disconnected")
|
748
|
+
except Exception as e:
|
749
|
+
print(f"Error disconnecting socket: {e}")
|
750
|
+
|
751
|
+
for streamName, records in results.items():
|
752
|
+
dataframe[streamName] = None
|
753
|
+
for item in records:
|
754
|
+
for compound_key, value in item.items():
|
755
|
+
# for compound_key, value in item['data'].items():
|
756
|
+
|
757
|
+
rowID = compound_key.split('-')[0]
|
758
|
+
# looking for the index of each rowID , in the original dataframe
|
759
|
+
if rowID in rowIdMapping:
|
760
|
+
index = rowIdMapping[rowID]
|
761
|
+
# dataframe.at[index, evalName] = value
|
762
|
+
dataframe.at[index, streamName] = value["value"]
|
763
|
+
|
764
|
+
|
765
|
+
|
766
|
+
else:
|
767
|
+
pass
|
768
|
+
# print(f"⚠️ Warning: Could not find rowID {rowID} in mapping")
|
769
|
+
|
770
|
+
return dataframe
|
771
|
+
|
772
|
+
|
773
|
+
|
774
|
+
def getId(self,workspaceID,streamName):
|
775
|
+
streamId=getStreamId(workspaceID,self.apiKey,streamName)
|
776
|
+
return streamId
|
777
|
+
|
778
|
+
|
779
|
+
|
559
780
|
class SafeDict(dict):
|
560
781
|
def __missing__(self, key):
|
561
782
|
return ""
|
llumo/exceptions.py
CHANGED
@@ -30,8 +30,10 @@ class LlumoAIError(Exception):
|
|
30
30
|
return LlumoAIError(f"error: {detail}")
|
31
31
|
|
32
32
|
@staticmethod
|
33
|
-
def InsufficientCredits():
|
34
|
-
return LlumoAIError(
|
33
|
+
def InsufficientCredits(details):
|
34
|
+
return LlumoAIError(details)
|
35
|
+
|
36
|
+
# return LlumoAIError("LLumo hits exhausted")
|
35
37
|
|
36
38
|
@staticmethod
|
37
39
|
def InvalidPromptTemplate():
|
@@ -42,4 +44,8 @@ class LlumoAIError(Exception):
|
|
42
44
|
|
43
45
|
@staticmethod
|
44
46
|
def modelHitsExhausted(details = "Your credits for the selected model exhausted."):
|
45
|
-
return LlumoAIError(details)
|
47
|
+
return LlumoAIError(details)
|
48
|
+
|
49
|
+
# @staticmethod
|
50
|
+
# def dateNotFound():
|
51
|
+
# return LlumoAIError("Trial end date or subscription end date not found for the given user.")
|
llumo/helpingFuntions.py
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
import time
|
2
2
|
import uuid
|
3
3
|
import numpy as np
|
4
|
+
from datetime import datetime
|
5
|
+
from dateutil import parser
|
6
|
+
import requests
|
7
|
+
import json
|
8
|
+
import base64
|
9
|
+
import os
|
10
|
+
from dotenv import load_dotenv
|
11
|
+
load_dotenv()
|
12
|
+
|
13
|
+
subscriptionUrl = os.getenv("SUBSCRIPTION_URL")
|
14
|
+
getStreamdataUrl = os.getenv("DATA_STREAM_URL")
|
15
|
+
|
16
|
+
|
4
17
|
|
5
18
|
def getProcessID():
|
6
19
|
return f"{int(time.time() * 1000)}{uuid.uuid4()}"
|
@@ -48,3 +61,77 @@ def costColumnMapping(costResults, allProcess):
|
|
48
61
|
cost_saving.append("error occured")
|
49
62
|
|
50
63
|
return compressed_prompt, compressed_prompt_output, cost, cost_saving
|
64
|
+
|
65
|
+
|
66
|
+
def checkUserHits(workspaceID, hasSubscribed, trialEndDate, subscriptionEndDate, remainingHits, datasetLength):
|
67
|
+
# Get the current date (only the date part)
|
68
|
+
current_date = datetime.now().date()
|
69
|
+
|
70
|
+
# Parse trialEndDate if provided
|
71
|
+
if trialEndDate is not None:
|
72
|
+
try:
|
73
|
+
trialEndDate = parser.parse(trialEndDate).date()
|
74
|
+
except Exception:
|
75
|
+
return {"success": False, "message": "Invalid trialEndDate format"}
|
76
|
+
|
77
|
+
# Parse subscriptionEndDate if provided
|
78
|
+
if subscriptionEndDate is not None:
|
79
|
+
try:
|
80
|
+
subscriptionEndDate = parser.parse(subscriptionEndDate).date()
|
81
|
+
except Exception:
|
82
|
+
return {"success": False, "message": "Invalid subscriptionEndDate format"}
|
83
|
+
|
84
|
+
# If user is on a free trial
|
85
|
+
if not hasSubscribed and trialEndDate is not None:
|
86
|
+
if current_date > trialEndDate:
|
87
|
+
return {"success": False, "message": "Trial expired. Access denied"}
|
88
|
+
|
89
|
+
if remainingHits < datasetLength or remainingHits <= 0:
|
90
|
+
return {"success": False, "message": "Trial Hits Exhausted"}
|
91
|
+
|
92
|
+
else:
|
93
|
+
if subscriptionEndDate and current_date > subscriptionEndDate:
|
94
|
+
return {"success": False, "message": "Subscription expired. Access denied."}
|
95
|
+
|
96
|
+
if remainingHits <= 0 or remainingHits < datasetLength:
|
97
|
+
headers = {
|
98
|
+
"Authorization": f"Bearer {base64.b64encode(workspaceID.encode()).decode()}",
|
99
|
+
"Content-Type": "application/json",
|
100
|
+
}
|
101
|
+
reqBody = {"unitsToSet": 1}
|
102
|
+
responseBody = requests.post(url=subscriptionUrl, json=reqBody, headers=headers)
|
103
|
+
response = json.loads(responseBody.text)
|
104
|
+
|
105
|
+
proceed = response.get("execution", "")
|
106
|
+
print(proceed)
|
107
|
+
|
108
|
+
if proceed:
|
109
|
+
return {"success": True, "message": "Hits added and access granted."}
|
110
|
+
|
111
|
+
return {"success": True, "message": "Access granted."}
|
112
|
+
|
113
|
+
def getStreamId(workspaceID: str, token, dataStreamName):
|
114
|
+
headers = {
|
115
|
+
"Authorization": f"Bearer {token}",
|
116
|
+
"Content-Type": "application/json",
|
117
|
+
}
|
118
|
+
reqBody = {"workspaceID": workspaceID}
|
119
|
+
response = requests.post(url=getStreamdataUrl, json=reqBody, headers=headers)
|
120
|
+
|
121
|
+
if response.status_code == 200:
|
122
|
+
responseJson = response.json()
|
123
|
+
data = responseJson.get("data", [])
|
124
|
+
|
125
|
+
# Find stream by name
|
126
|
+
matchedStream = next((stream for stream in data if stream.get("name") == dataStreamName), None)
|
127
|
+
|
128
|
+
if matchedStream:
|
129
|
+
|
130
|
+
return matchedStream.get("dataStreamID")
|
131
|
+
|
132
|
+
else:
|
133
|
+
print(f"No stream found with name: {dataStreamName}")
|
134
|
+
return None
|
135
|
+
else:
|
136
|
+
print("Error:", response.status_code, response.text)
|
137
|
+
return None
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: llumo
|
3
|
+
Version: 0.1.9b10
|
4
|
+
Summary: Python SDK for interacting with the Llumo ai API.
|
5
|
+
Home-page: https://www.llumo.ai/
|
6
|
+
Author: Llumo
|
7
|
+
Author-email: product@llumo.ai
|
8
|
+
Requires-Python: >=3.7
|
9
|
+
Description-Content-Type: text/markdown
|
10
|
+
License-File: LICENSE
|
11
|
+
Dynamic: author
|
12
|
+
Dynamic: author-email
|
13
|
+
Dynamic: description-content-type
|
14
|
+
Dynamic: home-page
|
15
|
+
Dynamic: license-file
|
16
|
+
Dynamic: requires-python
|
17
|
+
Dynamic: summary
|
@@ -0,0 +1,13 @@
|
|
1
|
+
llumo/__init__.py,sha256=O04b4yW1BnOvcHzxWFddAKhtdBEhBNhLdb6xgnpHH_Q,205
|
2
|
+
llumo/client.py,sha256=F4zabvAjLnu0N61qSw5DqerNlV5ybC2DbxaI55olldg,31916
|
3
|
+
llumo/exceptions.py,sha256=iCj7HhtO_ckC2EaVBdXbAudNpuMDsYmmMEV5lwynZ-E,1854
|
4
|
+
llumo/execution.py,sha256=x88wQV8eL99wNN5YtjFaAMCIfN1PdfQVlAZQb4vzgQ0,1413
|
5
|
+
llumo/functionCalling.py,sha256=QtuTtyoz5rnfNUrNT1kzegNPOrMFjrlgxZfwTqRMdiA,7190
|
6
|
+
llumo/helpingFuntions.py,sha256=9w1J4wMnJV1v_5yFMyxIHcvc16sEq5MZzOFBPagij5Q,4467
|
7
|
+
llumo/models.py,sha256=YH-qAMnShmUpmKE2LQAzQdpRsaXkFSlOqMxHwU4zBUI,1560
|
8
|
+
llumo/sockets.py,sha256=Qxxqtx3Hg07HLhA4QfcipK1ChiOYhHZBu02iA6MfYlQ,5579
|
9
|
+
llumo-0.1.9b10.dist-info/licenses/LICENSE,sha256=tF9yAcfPV9xGT3ViWmC8hPvOo8BEk4ZICbUfcEo8Dlk,182
|
10
|
+
llumo-0.1.9b10.dist-info/METADATA,sha256=QkiIW2Z2Lk86q5v9Reg4Pq0bNPTpWXR6NWGT0aW-Esk,429
|
11
|
+
llumo-0.1.9b10.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
12
|
+
llumo-0.1.9b10.dist-info/top_level.txt,sha256=d5zUTMI99llPtLRB8rtSrqELm_bOqX-bNC5IcwlDk88,6
|
13
|
+
llumo-0.1.9b10.dist-info/RECORD,,
|
llumo-0.1.8.dist-info/METADATA
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: llumo
|
3
|
-
Version: 0.1.8
|
4
|
-
Summary: Python SDK for interacting with the Llumo ai API.
|
5
|
-
Home-page: https://www.llumo.ai/
|
6
|
-
Author: Llumo
|
7
|
-
Author-email: product@llumo.ai
|
8
|
-
License: Proprietary
|
9
|
-
Requires-Python: >=3.7
|
10
|
-
License-File: LICENSE
|
11
|
-
Requires-Dist: requests>=2.0.0
|
12
|
-
Requires-Dist: websocket-client>=1.0.0
|
13
|
-
Requires-Dist: pandas>=1.0.0
|
14
|
-
Requires-Dist: numpy>=1.0.0
|
15
|
-
Requires-Dist: python-socketio[client]==5.13.0
|
16
|
-
Requires-Dist: python-dotenv==1.1.0
|
17
|
-
Requires-Dist: openai==1.75.0
|
18
|
-
Requires-Dist: google-generativeai==0.8.5
|
19
|
-
Dynamic: author
|
20
|
-
Dynamic: author-email
|
21
|
-
Dynamic: home-page
|
22
|
-
Dynamic: license
|
23
|
-
Dynamic: license-file
|
24
|
-
Dynamic: requires-dist
|
25
|
-
Dynamic: requires-python
|
26
|
-
Dynamic: summary
|
llumo-0.1.8.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
llumo/__init__.py,sha256=O04b4yW1BnOvcHzxWFddAKhtdBEhBNhLdb6xgnpHH_Q,205
|
2
|
-
llumo/client.py,sha256=Qc-LTgAiW4D8Q18oZlkNTDP8Csd_fPDI41zYaXkFD1M,22437
|
3
|
-
llumo/exceptions.py,sha256=KGmztP61dkkzCTBEiRv5Xe9HrLNv1s_fYioRCG64GUU,1656
|
4
|
-
llumo/execution.py,sha256=x88wQV8eL99wNN5YtjFaAMCIfN1PdfQVlAZQb4vzgQ0,1413
|
5
|
-
llumo/functionCalling.py,sha256=QtuTtyoz5rnfNUrNT1kzegNPOrMFjrlgxZfwTqRMdiA,7190
|
6
|
-
llumo/helpingFuntions.py,sha256=BWRoAAXG3Dsovc9bk-pDD2feQM_3ERXz_MwNgux0e7Q,1418
|
7
|
-
llumo/models.py,sha256=YH-qAMnShmUpmKE2LQAzQdpRsaXkFSlOqMxHwU4zBUI,1560
|
8
|
-
llumo/sockets.py,sha256=Qxxqtx3Hg07HLhA4QfcipK1ChiOYhHZBu02iA6MfYlQ,5579
|
9
|
-
llumo-0.1.8.dist-info/licenses/LICENSE,sha256=tF9yAcfPV9xGT3ViWmC8hPvOo8BEk4ZICbUfcEo8Dlk,182
|
10
|
-
llumo-0.1.8.dist-info/METADATA,sha256=nRQD4QA9Bf5OPisfsG4tjJwXN4fg5eADW1YuDxvZ-dg,695
|
11
|
-
llumo-0.1.8.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
|
12
|
-
llumo-0.1.8.dist-info/top_level.txt,sha256=d5zUTMI99llPtLRB8rtSrqELm_bOqX-bNC5IcwlDk88,6
|
13
|
-
llumo-0.1.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|