llumo 0.1.7__py3-none-any.whl → 0.1.9__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 CHANGED
@@ -149,168 +149,149 @@ class LlumoClient:
149
149
 
150
150
  return uniqueResults
151
151
 
152
- def evaluate(self, dataframe, evals=["Response Completeness"], prompt_template="",outputColName = "output"):
153
-
152
+ def evaluate(self, dataframe, eval ="Response Completeness", prompt_template="", outputColName="output"):
154
153
 
155
154
  results = {}
156
155
  try:
157
- # Connect to socket first
158
- # print("Connecting to socket server...")
159
- socketID = self.socket.connect(timeout=30)
160
- # print(f"Connected with socket ID: {socketID}")
156
+ socketID = self.socket.connect(timeout=150)
157
+
158
+ # Ensure full connection before proceeding
159
+ max_wait_secs = 20
160
+ waited_secs = 0
161
+ while not self.socket._connection_established.is_set():
162
+ time.sleep(0.1)
163
+ waited_secs += 0.1
164
+ if waited_secs >= max_wait_secs:
165
+ raise RuntimeError("Timeout waiting for server 'connection-established' event.")
161
166
 
162
- # Store the mapping of row IDs to dataframe indices
163
167
  rowIdMapping = {}
164
168
 
165
- # Process each evaluation
166
- for eval in evals:
167
- print(f"\n======= Running evaluation for: {eval} =======")
168
169
 
169
- try:
170
- # print(f"Validating API key for {eval}...")
171
- self.validateApiKey(evalName=eval)
172
- # print(f"API key validation successful. Hits available: {self.hitsAvailable}")
173
- except Exception as e:
174
- # print(f"Error during API key validation: {str(e)}")
175
- if hasattr(e, "response") and getattr(e, "response", None) is not None:
176
- # print(f"Status code: {e.response.status_code}")
177
- # print(f"Response content: {e.response.text[:500]}...")
178
- pass
179
- raise
180
-
181
- if self.hitsAvailable == 0 or len(dataframe) > self.hitsAvailable:
182
- raise LlumoAIError.InsufficientCredits()
183
-
184
- evalDefinition = self.evalDefinition[eval]
185
- model = "GPT_4"
186
- provider = "OPENAI"
187
- evalType = "LLM"
188
- workspaceID = self.workspaceID
189
-
190
- # Prepare all batches before sending
191
- # print("Preparing batches...")
192
- self.allBatches = []
193
- currentBatch = []
194
-
195
- for index, row in dataframe.iterrows():
196
- tools = [row["tools"]] if "tools" in dataframe.columns else []
197
- groundTruth = row["groundTruth"] if "groundTruth" in dataframe.columns else ""
198
- messageHistory = [row["messageHistory"]] if "messageHistory" in dataframe.columns else []
199
- promptTemplate = prompt_template
200
-
201
- keys = re.findall(r"{{(.*?)}}", promptTemplate)
202
-
203
- # raise error if the prompt template is not in expected format
204
- if not all([ky in dataframe.columns for ky in keys]):
205
- raise LlumoAIError.InvalidPromptTemplate()
206
-
207
- inputDict = {key: row[key] for key in keys if key in row}
208
-
209
-
210
- output = row[outputColName] if outputColName in dataframe.columns else ""
211
-
212
- activePlayground = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
213
- rowID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
214
- columnID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
215
-
216
- rowIdMapping[rowID] = index
217
-
218
- templateData = {
219
- "processID": getProcessID(),
220
- "socketID": socketID,
221
- "source": "SDK",
222
- "processData": {
223
- "executionDependency": {
224
- "query": "",
225
- "context": "",
226
- "output": output,
227
- "tools": tools,
228
- "groundTruth": groundTruth,
229
- "messageHistory": messageHistory,
230
- },
231
- "definition": evalDefinition,
232
- "model": model,
233
- "provider": provider,
234
- "analytics": eval,
170
+ print(f"\n======= Running evaluation for: {eval} =======")
171
+
172
+ try:
173
+ self.validateApiKey(evalName=eval)
174
+ except Exception as e:
175
+ if hasattr(e, "response") and getattr(e, "response", None) is not None:
176
+ pass
177
+ raise
178
+
179
+ if self.hitsAvailable == 0 or len(dataframe) > self.hitsAvailable:
180
+ raise LlumoAIError.InsufficientCredits()
181
+
182
+ evalDefinition = self.evalDefinition[eval]
183
+ model = "GPT_4"
184
+ provider = "OPENAI"
185
+ evalType = "LLM"
186
+ workspaceID = self.workspaceID
187
+
188
+ self.allBatches = []
189
+ currentBatch = []
190
+
191
+ for index, row in dataframe.iterrows():
192
+ tools = [row["tools"]] if "tools" in dataframe.columns else []
193
+ groundTruth = row["groundTruth"] if "groundTruth" in dataframe.columns else ""
194
+ messageHistory = [row["messageHistory"]] if "messageHistory" in dataframe.columns else []
195
+ promptTemplate = prompt_template
196
+
197
+ keys = re.findall(r"{{(.*?)}}", promptTemplate)
198
+
199
+ if not all([ky in dataframe.columns for ky in keys]):
200
+ raise LlumoAIError.InvalidPromptTemplate()
201
+
202
+ inputDict = {key: row[key] for key in keys if key in row}
203
+ output = row[outputColName] if outputColName in dataframe.columns else ""
204
+
205
+ activePlayground = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
206
+ rowID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
207
+ columnID = f"{int(time.time() * 1000)}{uuid.uuid4()}".replace("-", "")
208
+
209
+ rowIdMapping[rowID] = index
210
+
211
+ templateData = {
212
+ "processID": getProcessID(),
213
+ "socketID": socketID,
214
+ "source": "SDK",
215
+ "processData": {
216
+ "executionDependency": {
217
+ "query": "",
218
+ "context": "",
219
+ "output": output,
220
+ "tools": tools,
221
+ "groundTruth": groundTruth,
222
+ "messageHistory": messageHistory,
235
223
  },
236
- "workspaceID": workspaceID,
237
- "type": "EVAL",
238
- "evalType": evalType,
239
- "kpi": eval,
240
- "columnID": columnID,
241
- "rowID": rowID,
242
- "playgroundID": activePlayground,
243
- "processType": "EVAL",
244
- }
224
+ "definition": evalDefinition,
225
+ "model": model,
226
+ "provider": provider,
227
+ "analytics": eval,
228
+ },
229
+ "workspaceID": workspaceID,
230
+ "type": "EVAL",
231
+ "evalType": evalType,
232
+ "kpi": eval,
233
+ "columnID": columnID,
234
+ "rowID": rowID,
235
+ "playgroundID": activePlayground,
236
+ "processType": "EVAL",
237
+ }
245
238
 
246
- query = ""
247
- context = ""
248
- for key, value in inputDict.items():
249
- if isinstance(value, str):
250
- length = len(value.split()) * 1.5
251
- if length > 50:
252
- context += f" {key}: {value}, "
253
- else:
254
- if promptTemplate:
255
- tempObj = {key: value}
256
- promptTemplate = getInputPopulatedPrompt(promptTemplate, tempObj)
257
- else:
258
- query += f" {key}: {value}, "
259
-
260
- if not context.strip():
261
- for key, value in inputDict.items():
239
+ query = ""
240
+ context = ""
241
+ for key, value in inputDict.items():
242
+ if isinstance(value, str):
243
+ length = len(value.split()) * 1.5
244
+ if length > 50:
262
245
  context += f" {key}: {value}, "
246
+ else:
247
+ if promptTemplate:
248
+ tempObj = {key: value}
249
+ promptTemplate = getInputPopulatedPrompt(promptTemplate, tempObj)
250
+ else:
251
+ query += f" {key}: {value}, "
263
252
 
264
- templateData["processData"]["executionDependency"]["context"] = context.strip()
265
- templateData["processData"]["executionDependency"]["query"] = query.strip()
266
-
267
- if promptTemplate and not query.strip():
268
- templateData["processData"]["executionDependency"]["query"] = promptTemplate
253
+ if not context.strip():
254
+ for key, value in inputDict.items():
255
+ context += f" {key}: {value}, "
269
256
 
270
- currentBatch.append(templateData)
257
+ templateData["processData"]["executionDependency"]["context"] = context.strip()
258
+ templateData["processData"]["executionDependency"]["query"] = query.strip()
271
259
 
272
- if len(currentBatch) == 10 or index == len(dataframe) - 1:
273
- self.allBatches.append(currentBatch)
274
- currentBatch = []
260
+ if promptTemplate and not query.strip():
261
+ templateData["processData"]["executionDependency"]["query"] = promptTemplate
275
262
 
276
- totalItems = sum(len(batch) for batch in self.allBatches)
277
- # print(f"Posting {len(self.allBatches)} batches ({totalItems } items total)")
263
+ currentBatch.append(templateData)
278
264
 
279
- for cnt, batch in enumerate(self.allBatches):
280
- # print(f"Posting batch {cnt + 1}/{len(self.allBatches)} for eval '{eval}'")
281
- try:
282
- self.postBatch(batch=batch, workspaceID=workspaceID)
283
- # print(f"Batch {cnt + 1} posted successfully")
284
- except Exception as e:
285
- # print(f"Error posting batch {cnt + 1}: {str(e)}")
286
- continue
265
+ if len(currentBatch) == 10 or index == len(dataframe) - 1:
266
+ self.allBatches.append(currentBatch)
267
+ currentBatch = []
287
268
 
288
- time.sleep(1)
269
+ totalItems = sum(len(batch) for batch in self.allBatches)
289
270
 
290
- timeout = max(60, min(600, totalItems * 10))
291
- # print(f"All batches posted. Waiting up to {timeout} seconds for results...")
271
+ for cnt, batch in enumerate(self.allBatches):
272
+ try:
273
+ self.postBatch(batch=batch, workspaceID=workspaceID)
274
+ # print("Betch Posted with item len: ", len(batch))
275
+ except Exception as e:
276
+ continue
292
277
 
293
- self.socket.listenForResults(
294
- min_wait=40, max_wait=timeout, inactivity_timeout=40
295
- )
278
+ time.sleep(1)
296
279
 
297
- eval_results = self.socket.getReceivedData()
298
- # print(f"Received {len(eval_results)} results for evaluation '{eval}'")
280
+ timeout = max(50, min(600, totalItems * 10))
299
281
 
300
- results[eval] = self.finalResp(eval_results)
301
- # print(f"======= Completed evaluation: {eval} =======\n")
282
+ self.socket.listenForResults(
283
+ min_wait=40, max_wait=timeout, inactivity_timeout=150, expected_results=totalItems
284
+ )
302
285
 
303
- # print("All evaluations completed successfully")
286
+ eval_results = self.socket.getReceivedData()
287
+ results[eval] = self.finalResp(eval_results)
304
288
 
305
289
  except Exception as e:
306
- # print(f"Error during evaluation: {e}")
307
290
  raise
308
291
  finally:
309
292
  try:
310
293
  self.socket.disconnect()
311
- # print("Socket disconnected")
312
294
  except Exception as e:
313
- # print(f"Error disconnecting socket: {e}")
314
295
  pass
315
296
 
316
297
  for evalName, records in results.items():
@@ -322,17 +303,28 @@ class LlumoClient:
322
303
  index = rowIdMapping[rowID]
323
304
  dataframe.at[index, evalName] = value
324
305
  else:
325
- print(f"Warning: Could not find rowID {rowID} in mapping")
326
306
  pass
307
+ # print(f"⚠️ Warning: Could not find rowID {rowID} in mapping")
327
308
 
328
309
  return dataframe
329
310
 
330
311
  def evaluateCompressor(self, dataframe, prompt_template):
331
312
  results = []
313
+
332
314
  try:
333
315
  # Connect to socket first
334
316
  # print("Connecting to socket server...")
335
- socketID = self.socket.connect(timeout=30)
317
+ socketID = self.socket.connect(timeout=150)
318
+
319
+ # Ensure full connection before proceeding
320
+ max_wait_secs = 20
321
+ waited_secs = 0
322
+ while not self.socket._connection_established.is_set():
323
+ time.sleep(0.1)
324
+ waited_secs += 0.1
325
+ if waited_secs >= max_wait_secs:
326
+ raise RuntimeError("Timeout waiting for server 'connection-established' event.")
327
+
336
328
  # print(f"Connected with socket ID: {socketID}")
337
329
 
338
330
  try:
@@ -443,7 +435,7 @@ class LlumoClient:
443
435
  if promptTemplate and not query.strip():
444
436
  templateData["processData"]["rowData"]["query"]["value"] = promptTemplate
445
437
 
446
- print(templateData)
438
+ # print(templateData)
447
439
  currentBatch.append(templateData)
448
440
 
449
441
  if len(currentBatch) == 10 or index == len(dataframe) - 1:
@@ -452,13 +444,13 @@ class LlumoClient:
452
444
 
453
445
  # Post all batches
454
446
  total_items = sum(len(batch) for batch in self.allBatches)
455
- print(f"Posting {len(self.allBatches)} batches ({total_items} items total)")
447
+ # print(f"Posting {len(self.allBatches)} batches ({total_items} items total)")
456
448
 
457
449
  for cnt, batch in enumerate(self.allBatches):
458
- print(f"Posting batch {cnt + 1}/{len(self.allBatches)} for eval '{eval}'")
450
+ # print(f"Posting batch {cnt + 1}/{len(self.allBatches)} for eval '{eval}'")
459
451
  try:
460
452
  self.postBatch(batch=batch, workspaceID=workspaceID)
461
- print(f"Batch {cnt + 1} posted successfully")
453
+ # print(f"Batch {cnt + 1} posted successfully")
462
454
  except Exception as e:
463
455
  print(f"Error posting batch {cnt + 1}: {str(e)}")
464
456
  continue
@@ -473,7 +465,7 @@ class LlumoClient:
473
465
  # print(f"All batches posted. Waiting up to {timeout} seconds for results...")
474
466
 
475
467
  # Listen for results
476
- self.socket.listenForResults(min_wait=20, max_wait=timeout, inactivity_timeout=30)
468
+ self.socket.listenForResults(min_wait=20, max_wait=timeout, inactivity_timeout=30,expected_results=None)
477
469
 
478
470
  # Get results for this evaluation
479
471
  eval_results = self.socket.getReceivedData()
@@ -504,7 +496,7 @@ class LlumoClient:
504
496
  return dataframe
505
497
 
506
498
 
507
- def run_sweep(self,templates: List[str], dataset: Dict[str, List[str]], model_aliases: List[AVAILABLEMODELS], apiKey: str, evals = ["Response Correctness"]) -> pd.DataFrame:
499
+ def run_sweep(self,templates: List[str], dataset: Dict[str, List[str]], model_aliases: List[AVAILABLEMODELS], apiKey: str, eval = ["Response Correctness"],toEvaluate:bool =False ) -> pd.DataFrame:
508
500
  executor = ModelExecutor(apiKey)
509
501
 
510
502
  keys = list(dataset.keys())
@@ -538,10 +530,12 @@ class LlumoClient:
538
530
 
539
531
  results.append(row)
540
532
  df=pd.DataFrame(results)
533
+ if toEvaluate:
534
+
535
+ res = self.evaluate(df,eval =eval ,prompt_template=str(templates[0]))
536
+ return res
541
537
 
542
- print(str(templates[0]))
543
- res = self.evaluate(df,evals =evals,prompt_template=str(templates[0]))
544
- return res
538
+ return df
545
539
 
546
540
  def evaluateAgents(self, dataframe, model, agents, model_api_key=None,
547
541
  prompt_template="Give answer for the given query: {{query}}"):
@@ -550,13 +544,15 @@ class LlumoClient:
550
544
 
551
545
  # Run unified agent execution
552
546
  toolResponseDf = LlumoAgentExecutor.run(dataframe, agents, model=model, model_api_key=model_api_key)
553
-
554
- # Perform evaluation
555
- res = self.evaluate(
556
- toolResponseDf,
557
- evals=["Tool Reliability", "Stepwise Progression", "Tool Selection Accuracy", "Final Task Alignment"],
558
- prompt_template=prompt_template
559
- )
547
+ evals = ["Tool Reliability", "Stepwise Progression", "Tool Selection Accuracy", "Final Task Alignment"]
548
+
549
+ for eval in evals:
550
+ # Perform evaluation
551
+ toolResponseDf = self.evaluate(
552
+ toolResponseDf,
553
+ eval = eval,
554
+ prompt_template=prompt_template
555
+ )
560
556
  return toolResponseDf
561
557
 
562
558
 
llumo/functionCalling.py CHANGED
@@ -176,8 +176,9 @@ class LlumoAgentExecutor:
176
176
  messageHistories.append(str(messages))
177
177
 
178
178
  except Exception as e:
179
- results.append(f"Error during processing: {e}")
180
- messageHistories.append("Error in conversation")
179
+ # results.append(f"Error during processing: {e}")
180
+ # messageHistories.append("Error in conversation")
181
+ raise LlumoAIError.modelHitsExhausted()
181
182
 
182
183
  df["output"] = results
183
184
  df["messageHistory"] = messageHistories
llumo/sockets.py CHANGED
@@ -13,13 +13,14 @@ class LlumoSocketClient:
13
13
  self._lock = threading.Lock()
14
14
  self._connected = False
15
15
  self.server_socket_id = None # Store the server-assigned socket ID
16
+ self._expected_results = None # NEW
16
17
 
17
18
  # Initialize client
18
19
  self.sio = socketio.Client(
19
20
  # logger=True,
20
21
  # engineio_logger=True,
21
22
  reconnection=True,
22
- reconnection_attempts=5,
23
+ reconnection_attempts=10,
23
24
  reconnection_delay=1,
24
25
  )
25
26
 
@@ -47,6 +48,11 @@ class LlumoSocketClient:
47
48
  self._received_data.append(data)
48
49
  self._last_update_time = time.time()
49
50
 
51
+ # ✅ Stop if all expected results are received
52
+ if self._expected_results and len(self._received_data) >= self._expected_results:
53
+ # print("✅ All expected results received.")
54
+ self._listening_done.set()
55
+
50
56
  @self.sio.on("disconnect")
51
57
  def on_disconnect():
52
58
  # print("Socket disconnected")
@@ -65,38 +71,40 @@ class LlumoSocketClient:
65
71
  self._connection_established.clear()
66
72
  self._listening_done.clear()
67
73
  self.server_socket_id = None
74
+ self._connected = False
68
75
 
69
76
  try:
70
- # print("Attempting direct WebSocket connection...")
71
- # Connect with websocket transport
77
+ # print("[DEBUG] Connecting to socket...")
72
78
  self.sio.connect(self.socket_url, transports=["websocket"], wait=True)
73
79
 
74
- # print(f"Engine.IO connection established with SID: {self.sio.sid}")
75
- # print( "Waiting for server to acknowledge connection with connection-established event...")
80
+ # Wait for socket connection
81
+ start = time.time()
82
+ while not self.sio.connected:
83
+ if time.time() - start > timeout:
84
+ raise RuntimeError("Timed out waiting for low-level socket connection.")
85
+ time.sleep(0.1)
86
+ # print("[DEBUG] SocketIO low-level connection established.")
76
87
 
77
- # Wait for the connection-established event
88
+ # Wait for server "connection-established" event
78
89
  if not self._connection_established.wait(timeout):
79
- raise RuntimeError("Timed out waiting for connection-established event")
90
+ raise RuntimeError("Timed out waiting for connection-established event.")
80
91
 
92
+ self._connected = True
81
93
  self._last_update_time = time.time()
82
- # print(f"Connection fully established. Server socket ID: {self.server_socket_id}")
94
+ # print(f"[DEBUG] Full connection established. Connected: {self._connected}")
83
95
 
84
- # Return the server-assigned socket ID if available, otherwise fall back to the client's SID
85
96
  return self.server_socket_id or self.sio.sid
97
+
86
98
  except Exception as e:
99
+ # print(f"[DEBUG] Connection failed with error: {e}")
87
100
  self._connected = False
88
101
  raise RuntimeError(f"WebSocket connection failed: {e}")
89
102
 
90
- def listenForResults(self, min_wait=30, max_wait=300, inactivity_timeout=50):
91
- """
92
- Listen for results with improved timeout handling:
93
- - min_wait: Minimum time to wait even if no data is received
94
- - max_wait: Maximum total time to wait for results
95
- - inactivity_timeout: Time to wait after last data received
96
- """
103
+ def listenForResults(self, min_wait=30, max_wait=300, inactivity_timeout=50, expected_results=None):
97
104
  if not self._connected:
98
105
  raise RuntimeError("WebSocket is not connected. Call connect() first.")
99
106
 
107
+ self._expected_results = expected_results # NEW
100
108
  start_time = time.time()
101
109
  self._last_update_time = time.time()
102
110
 
@@ -106,31 +114,25 @@ class LlumoSocketClient:
106
114
  time_since_last_update = current_time - self._last_update_time
107
115
  total_elapsed = current_time - start_time
108
116
 
109
- # Always wait for minimum time
110
117
  if total_elapsed < min_wait:
111
118
  time.sleep(0.5)
112
119
  continue
113
120
 
114
- # Stop if maximum time exceeded
115
121
  if total_elapsed > max_wait:
116
- # print(f"⚠️ Maximum wait time of {max_wait}s reached, stopping listener.")
122
+ # print(f"⚠️ Max wait time {max_wait}s exceeded.")
117
123
  self._listening_done.set()
118
124
  break
119
125
 
120
- # Stop if no activity for inactivity_timeout
121
126
  if time_since_last_update > inactivity_timeout:
122
- # print(f"⚠️ No data received for {inactivity_timeout}s, stopping listener.")
127
+ # print(f"⚠️ Inactivity timeout {inactivity_timeout}s exceeded.")
123
128
  self._listening_done.set()
124
129
  break
125
130
 
126
- # Check every second
127
131
  time.sleep(1)
128
132
 
129
133
  timeout_thread = threading.Thread(target=timeout_watcher, daemon=True)
130
134
  timeout_thread.start()
131
- # print("Started listening for WebSocket events...")
132
135
  self._listening_done.wait()
133
- # print(f"Finished listening. Received {len(self._received_data)} data updates.")
134
136
 
135
137
  def getReceivedData(self):
136
138
  with self._lock:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llumo
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: Python SDK for interacting with the Llumo ai API.
5
5
  Home-page: https://www.llumo.ai/
6
6
  Author: Llumo
@@ -0,0 +1,14 @@
1
+ llumo/.env,sha256=Vx5FkuywpYHXH2N8epJ7PlNOPiwx9UP9DUz4vWd0urs,373
2
+ llumo/__init__.py,sha256=Ro08YEqv03qSyn54Gj8x2LUSLSZeXBQjvuODmMpqjHA,212
3
+ llumo/client.py,sha256=9QtL8xLH0doqkJIQqhNIaR3Mlma2hkiQsylFLfaboKs,22998
4
+ llumo/exceptions.py,sha256=bmYQYdTz2ooM0CYs3M4iHYxQrVmc46dNey_fCkiaUxo,1700
5
+ llumo/execution.py,sha256=jSkyI2l6bowum82RDI60Tkmoe2bVnrvkJnqr8mNWjBE,1451
6
+ llumo/functionCalling.py,sha256=_qVC987oR7nWIFmRSKDkysMgXC7tJycN6nUUniBusAc,7380
7
+ llumo/helpingFuntions.py,sha256=_eGra7Ci79eI2e37hSIq3CMN2bgdQUTv55PydITs5NI,1468
8
+ llumo/models.py,sha256=WBtnu7ckOy9TGRiwswz04xOGYF6EslTUOxHUz4QWzUA,1602
9
+ llumo/sockets.py,sha256=uehnOHKqZYKek4XN5ya348OmdED-hGTXRcO8onL1XUM,5727
10
+ llumo-0.1.9.dist-info/licenses/LICENSE,sha256=vMiqSi3KpDHq3RFxKiqdh10ZUF3PjE3nnntANU-HEu4,186
11
+ llumo-0.1.9.dist-info/METADATA,sha256=NpdYEwl-E-gmFVSLtfEyxafcZF8ykErKEvVha2VDIdY,721
12
+ llumo-0.1.9.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
13
+ llumo-0.1.9.dist-info/top_level.txt,sha256=d5zUTMI99llPtLRB8rtSrqELm_bOqX-bNC5IcwlDk88,6
14
+ llumo-0.1.9.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.1)
2
+ Generator: setuptools (80.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,14 +0,0 @@
1
- llumo/.env,sha256=Vx5FkuywpYHXH2N8epJ7PlNOPiwx9UP9DUz4vWd0urs,373
2
- llumo/__init__.py,sha256=Ro08YEqv03qSyn54Gj8x2LUSLSZeXBQjvuODmMpqjHA,212
3
- llumo/client.py,sha256=hrKH97PZ6i3KMfT7a6g3KzN_pzvpN8W5oMWMn2gO4tI,23986
4
- llumo/exceptions.py,sha256=bmYQYdTz2ooM0CYs3M4iHYxQrVmc46dNey_fCkiaUxo,1700
5
- llumo/execution.py,sha256=jSkyI2l6bowum82RDI60Tkmoe2bVnrvkJnqr8mNWjBE,1451
6
- llumo/functionCalling.py,sha256=JwCxK_TJcFZMPP7ujqsoYfrX45XLxQfGqmyOdlwAtcM,7315
7
- llumo/helpingFuntions.py,sha256=_eGra7Ci79eI2e37hSIq3CMN2bgdQUTv55PydITs5NI,1468
8
- llumo/models.py,sha256=WBtnu7ckOy9TGRiwswz04xOGYF6EslTUOxHUz4QWzUA,1602
9
- llumo/sockets.py,sha256=rxeUHaxwqg1vSlplohS-aLycbW125ocqk04RiV20Ldg,5835
10
- llumo-0.1.7.dist-info/licenses/LICENSE,sha256=vMiqSi3KpDHq3RFxKiqdh10ZUF3PjE3nnntANU-HEu4,186
11
- llumo-0.1.7.dist-info/METADATA,sha256=jwC_sLeRrvmw-uJv_xbVbn3AbeUBYWB7RaPzQdE3850,721
12
- llumo-0.1.7.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
13
- llumo-0.1.7.dist-info/top_level.txt,sha256=d5zUTMI99llPtLRB8rtSrqELm_bOqX-bNC5IcwlDk88,6
14
- llumo-0.1.7.dist-info/RECORD,,