lucidicai 1.2.13__tar.gz → 1.2.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.
- {lucidicai-1.2.13 → lucidicai-1.2.15}/PKG-INFO +1 -1
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/__init__.py +7 -20
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/model_pricing.py +14 -1
- lucidicai-1.2.15/lucidicai/singleton.py +50 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai.egg-info/PKG-INFO +1 -1
- {lucidicai-1.2.13 → lucidicai-1.2.15}/setup.py +1 -1
- lucidicai-1.2.13/lucidicai/singleton.py +0 -16
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/client.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/constants.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/errors.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/event.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/image_upload.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/__init__.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/anthropic_handler.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/base_providers.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/langchain.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/openai_agents_handler.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/openai_handler.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/opentelemetry_converter.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/providers/pydantic_ai_handler.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/session.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/step.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai/streaming.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai.egg-info/SOURCES.txt +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai.egg-info/dependency_links.txt +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai.egg-info/requires.txt +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/lucidicai.egg-info/top_level.txt +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/setup.cfg +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/tests/test_anthropic_comprehensive.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/tests/test_event_display.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/tests/test_openai_agents_9_patterns_fixed.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/tests/test_openai_comprehensive.py +0 -0
- {lucidicai-1.2.13 → lucidicai-1.2.15}/tests/test_pydantic_ai_comprehensive.py +0 -0
|
@@ -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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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()
|
|
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
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from .errors import LucidicNotInitializedError
|
|
2
|
+
|
|
3
|
+
lai_inst = {}
|
|
4
|
+
|
|
5
|
+
def singleton(class_):
|
|
6
|
+
def getinstance(*args, **kwargs):
|
|
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
|
+
|
|
27
|
+
return getinstance
|
|
28
|
+
|
|
29
|
+
def clear_singletons():
|
|
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,16 +0,0 @@
|
|
|
1
|
-
from .errors import LucidicNotInitializedError
|
|
2
|
-
|
|
3
|
-
lai_inst = {}
|
|
4
|
-
|
|
5
|
-
def singleton(class_):
|
|
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
|
-
|
|
13
|
-
return getinstance
|
|
14
|
-
|
|
15
|
-
def clear_singletons():
|
|
16
|
-
lai_inst.clear()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|