lucidicai 1.2.13__py3-none-any.whl → 1.2.15__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.
lucidicai/__init__.py CHANGED
@@ -130,15 +130,12 @@ def init(
130
130
  agent_id = os.getenv("LUCIDIC_AGENT_ID", None)
131
131
  if agent_id is None:
132
132
  raise APIKeyVerificationError("Lucidic agent ID not specified. Make sure to either pass your agent ID into lai.init() or set the LUCIDIC_AGENT_ID environment variable.")
133
- try:
134
- client = Client()
135
- if client.initialized:
136
- raise InvalidOperationError("[Lucidic] Session already in progress. Please call lai.reset() between sessions.")
137
- except LucidicNotInitializedError:
138
- client = Client(
139
- lucidic_api_key=lucidic_api_key,
140
- agent_id=agent_id,
141
- )
133
+
134
+ # get current client which will be NullClient if never lai is never initialized
135
+ client = Client()
136
+ # ff not yet initialized or still the NullClient -> creaet a real client when init is called
137
+ if not getattr(client, 'initialized', False):
138
+ client = Client(lucidic_api_key=lucidic_api_key, agent_id=agent_id)
142
139
 
143
140
  # Set up providers
144
141
  _setup_providers(client, providers)
@@ -201,9 +198,8 @@ def update_session(
201
198
  is_successful: Whether the session was successful.
202
199
  is_successful_reason: Session success reason.
203
200
  """
204
- client = Client() # TODO: Fail silently if client not initialized yet
201
+ client = Client()
205
202
  if not client.session:
206
- logger.warning("update_session called when session not initialized. Please call lai.init() first.")
207
203
  return
208
204
  client.session.update_session(**locals())
209
205
 
@@ -225,7 +221,6 @@ def end_session(
225
221
  """
226
222
  client = Client()
227
223
  if not client.session:
228
- logger.warning("end_session called when session not initialized. Please call lai.init() first.")
229
224
  return
230
225
  client.session.update_session(is_finished=True, **locals())
231
226
  client.clear()
@@ -237,7 +232,6 @@ def reset_sdk() -> None:
237
232
  """
238
233
  client = Client()
239
234
  if not client.initialized:
240
- logger.warning("reset_sdk called when SDK not initialized. Please call lai.init() first.")
241
235
  return
242
236
  client.clear()
243
237
 
@@ -307,7 +301,6 @@ def create_step(
307
301
  """
308
302
  client = Client()
309
303
  if not client.session:
310
- logger.warning("create_step called when session not initialized. Please call lai.init() first.")
311
304
  return
312
305
  return client.session.create_step(**locals())
313
306
 
@@ -337,7 +330,6 @@ def update_step(
337
330
  """
338
331
  client = Client()
339
332
  if not client.session:
340
- logger.warning("update_step called when session not initialized. Please call lai.init() first.")
341
333
  return
342
334
  if not client.session.active_step:
343
335
  raise InvalidOperationError("No active step to update")
@@ -369,7 +361,6 @@ def end_step(
369
361
  """
370
362
  client = Client()
371
363
  if not client.session:
372
- logger.warning("end_step called when session not initialized. Please call lai.init() first.")
373
364
  return
374
365
 
375
366
  if not client.session.active_step and step_id is None:
@@ -404,7 +395,6 @@ def create_event(
404
395
 
405
396
  client = Client()
406
397
  if not client.session:
407
- logger.warning("create_event called when session not initialized. Please call lai.init() first.")
408
398
  return
409
399
  return client.session.create_event(**locals())
410
400
 
@@ -430,7 +420,6 @@ def update_event(
430
420
  """
431
421
  client = Client()
432
422
  if not client.session:
433
- logger.warning("update_event called when session not initialized. Please call lai.init() first.")
434
423
  return
435
424
  client.session.update_event(**locals())
436
425
 
@@ -455,7 +444,6 @@ def end_event(
455
444
  """
456
445
  client = Client()
457
446
  if not client.session:
458
- logger.warning("end_event called when session not initialized. Please call lai.init() first.")
459
447
  return
460
448
  client.session.update_event(is_finished=True, **locals())
461
449
 
@@ -480,7 +468,6 @@ def get_prompt(
480
468
  """
481
469
  client = Client()
482
470
  if not client.session:
483
- logger.warning("get_prompt called when session not initialized, and will return an empty string. Please call lai.init() first.")
484
471
  return ""
485
472
  prompt = client.get_prompt(prompt_name, cache_ttl, label)
486
473
  if variables:
@@ -141,6 +141,7 @@ MODEL_PRICING = {
141
141
  "deepseek-ai/deepseek-r1-distill-llama-70b": {"input": 0.75, "output": 0.99},
142
142
  "deepseek-coder": {"input": 0.14, "output": 0.28},
143
143
  "deepseek-chat": {"input": 0.14, "output": 0.28},
144
+ "deepseek/deepseek-v3-0324": {"input": 0.14, "output": 0.28},
144
145
 
145
146
  # Qwen Models
146
147
  "qwen-qwq-32b": {"input": 0.29, "output": 0.39},
@@ -148,6 +149,8 @@ MODEL_PRICING = {
148
149
  "qwen-turbo": {"input": 0.3, "output": 0.6},
149
150
  "qwen-plus": {"input": 0.5, "output": 2.0},
150
151
  "qwen-max": {"input": 2.0, "output": 6.0},
152
+ "qwen2.5-32b-instruct": {"input": 0.7, "output": "2.8"},
153
+ "qwen2.5-max": {"input": 1.6, "output": 6.4},
151
154
 
152
155
  # Google Gemma Models
153
156
  "gemma-2-9b": {"input": 0.20, "output": 0.20},
@@ -163,7 +166,14 @@ MODEL_PRICING = {
163
166
  "pplx-7b-chat": {"input": 0.07, "output": 0.28},
164
167
  "pplx-70b-chat": {"input": 0.7, "output": 2.8},
165
168
  "pplx-7b-online": {"input": 0.07, "output": 0.28},
166
- "pplx-70b-online": {"input": 0.7, "output": 2.8}
169
+ "pplx-70b-online": {"input": 0.7, "output": 2.8},
170
+
171
+ # Grok Models
172
+ "grok-3-latest": {"input": 3, "output": 15},
173
+ "grok-3": {"input": 3, "output": 15},
174
+ "grok-3-fast": {"input": 5, "output": 25},
175
+ "grok-3-mini": {"input": 0.3, "output": 0.5},
176
+ "grok-3-mini-fast": {"input": 0.6, "output": 4},
167
177
 
168
178
  }
169
179
 
@@ -179,6 +189,7 @@ PROVIDER_AVERAGES = {
179
189
  "qwen": {"input": 0.5, "output": 1.0}, # Qwen average
180
190
  "together": {"input": 0.15, "output": 0.15}, # Together AI average
181
191
  "perplexity": {"input": 0.4, "output": 1.5}, # Perplexity average
192
+ "grok": {"input": 2.4, "output": 12}, # Grok average
182
193
  }
183
194
 
184
195
  def get_provider_from_model(model: str) -> str:
@@ -205,6 +216,8 @@ def get_provider_from_model(model: str) -> str:
205
216
  return "together"
206
217
  elif any(pplx in model_lower for pplx in ["pplx", "perplexity"]):
207
218
  return "perplexity"
219
+ elif any(grok in model_lower for grok in ["grok", "xAI"]):
220
+ return "grok"
208
221
  else:
209
222
  return "unknown"
210
223
 
lucidicai/singleton.py CHANGED
@@ -4,13 +4,47 @@ lai_inst = {}
4
4
 
5
5
  def singleton(class_):
6
6
  def getinstance(*args, **kwargs):
7
- if class_ not in lai_inst:
8
- if class_.__name__ == 'Client' and ('lucidic_api_key' not in kwargs or 'agent_id' not in kwargs):
9
- raise LucidicNotInitializedError()
10
- lai_inst[class_] = class_(*args, **kwargs)
11
- return lai_inst[class_]
12
7
 
8
+ inst = lai_inst.get(class_)
9
+
10
+ # on first access -> no instance yet
11
+ if inst is None:
12
+ # no args/kwargs -> return a NullClient for Client
13
+ if class_.__name__ == 'Client' and not args and not kwargs:
14
+ inst = NullClient()
15
+ else:
16
+ inst = class_(*args, **kwargs)
17
+ lai_inst[class_] = inst
18
+ return inst
19
+
20
+ # existing instance present
21
+ # if NullClient and now real init args are passed -> upgrade it
22
+ if isinstance(inst, NullClient) and (args or kwargs):
23
+ inst = class_(*args, **kwargs)
24
+ lai_inst[class_] = inst
25
+ return inst
26
+
13
27
  return getinstance
14
28
 
15
29
  def clear_singletons():
16
30
  lai_inst.clear()
31
+
32
+
33
+ class NullClient:
34
+ """
35
+ A no-op client returned when Lucidic has not been initialized.
36
+ All methods are inert and session is None.
37
+ """
38
+ def __init__(self):
39
+ self.initialized = False
40
+ self.session = None
41
+ self.providers = []
42
+
43
+ def set_provider(self, *args, **kwargs):
44
+ pass
45
+
46
+ def undo_overrides(self):
47
+ pass
48
+
49
+ def clear(self):
50
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lucidicai
3
- Version: 1.2.13
3
+ Version: 1.2.15
4
4
  Summary: Lucidic AI Python SDK
5
5
  Author: Andy Liang
6
6
  Author-email: andy@lucidic.ai
@@ -1,13 +1,13 @@
1
- lucidicai/__init__.py,sha256=gYHjKKbjNwsY1uEcL4ogIJqHzKeabqKlKdz3H_XNGXY,18173
1
+ lucidicai/__init__.py,sha256=sNUGk7kd2IsjL39WgRkc7VuulRbFB5o1liK_65iEH9E,17034
2
2
  lucidicai/action.py,sha256=sPRd1hTIVXDqnvG9ZXWEipUFh0bsXcE0Fm7RVqmVccM,237
3
3
  lucidicai/client.py,sha256=axJ9JjDq6qIuyyYtiQlMREPTKD_eKve-0pOBKHH7HZg,5695
4
4
  lucidicai/constants.py,sha256=_u0z3M4geZgS1g-CrOZUVjtcew8l70dKQnpVQvlXh9w,2172
5
5
  lucidicai/errors.py,sha256=gTg0bdzjuTcUnakRbZnxjngO4gZnRLVwRHRglpZZJsM,970
6
6
  lucidicai/event.py,sha256=9Z1yuP7Pef0sdXABU9SCHCLZSu6DfK--uGZoq-a9_IA,1974
7
7
  lucidicai/image_upload.py,sha256=ShacoEaGXbQESatfp-CrIygsDntt9IkcCqZcc9uLZVQ,3130
8
- lucidicai/model_pricing.py,sha256=benQS2sp0-bboqP13e9l3ZYaYJcoqdIjHEaufCWoNw4,11599
8
+ lucidicai/model_pricing.py,sha256=Q_Kd8OtKPqtvZ4pIh__ztKb3RXe-cX-8xgrM-AIUj9E,12189
9
9
  lucidicai/session.py,sha256=goLQxBvXkLT5kS3eSfht3IFqvfYfgULC4eECSIanrPc,4909
10
- lucidicai/singleton.py,sha256=gmgei2mvCsgwng--Bb4Phk2wluvgS03zW3Cll6yQR9Y,477
10
+ lucidicai/singleton.py,sha256=gfT3XdWLXSIWMqDXbY6-pnesMZ8RGRitaEPhIsgrRPw,1272
11
11
  lucidicai/state.py,sha256=4Tb1X6l2or6w_e62FYSuEeghAv3xXm5gquKwzCpvdok,235
12
12
  lucidicai/step.py,sha256=egDmr3z3ZXu5nBJqeepj0Ml3ifDuyg07OwTB6vOJCaY,2462
13
13
  lucidicai/streaming.py,sha256=wQ32xMCHvaNaM6OQoAhY-yS5KoLi71KQPCbcxjpLzbU,11658
@@ -19,7 +19,7 @@ lucidicai/providers/openai_agents_handler.py,sha256=AAMtY7HZ-7UvTn1RVwd-uHhibJus
19
19
  lucidicai/providers/openai_handler.py,sha256=j2SW3YlGY1FhMO7d03WaIRxAtti6xATnoo2h8jh-uJk,35166
20
20
  lucidicai/providers/opentelemetry_converter.py,sha256=xOHCqoTyO4hUkL6k7fxy84PbljPpYep6ET9ZqbkJehc,17665
21
21
  lucidicai/providers/pydantic_ai_handler.py,sha256=Vu03SEqRuQNbmOK3iPwWVqczVRZNDDVoilDILIycK8c,28935
22
- lucidicai-1.2.13.dist-info/METADATA,sha256=JwKTQtiaKO8529OgFcPskeitCzAeKGLpFdTUHl3QV5o,577
23
- lucidicai-1.2.13.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
24
- lucidicai-1.2.13.dist-info/top_level.txt,sha256=vSSdM3lclF4I5tyVC0xxUk8eIRnnYXMe1hW-eO91HUo,10
25
- lucidicai-1.2.13.dist-info/RECORD,,
22
+ lucidicai-1.2.15.dist-info/METADATA,sha256=gM8vDiiFysOgG0OG6hcgnxYH4k2U1t1Mb0D_2cpfQfk,577
23
+ lucidicai-1.2.15.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
24
+ lucidicai-1.2.15.dist-info/top_level.txt,sha256=vSSdM3lclF4I5tyVC0xxUk8eIRnnYXMe1hW-eO91HUo,10
25
+ lucidicai-1.2.15.dist-info/RECORD,,