lucidicai 1.2.22__tar.gz → 1.3.0__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.22 → lucidicai-1.3.0}/PKG-INFO +1 -1
- {lucidicai-1.2.22 → lucidicai-1.3.0}/README.md +1 -1
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/__init__.py +39 -35
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/client.py +61 -15
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/event.py +1 -2
- lucidicai-1.3.0/lucidicai/lru.py +19 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/session.py +3 -29
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai.egg-info/PKG-INFO +1 -1
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai.egg-info/SOURCES.txt +1 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/setup.py +1 -1
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/constants.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/decorators.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/errors.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/image_upload.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/model_pricing.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/singleton.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/step.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/streaming.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/__init__.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/base_provider.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/litellm_bridge.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/lucidic_exporter.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/lucidic_span_processor.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/openai_agents_instrumentor.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/opentelemetry_converter.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/otel_handlers.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/otel_init.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/otel_provider.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/pydantic_ai_handler.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/utils/__init__.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/utils/image_storage.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/utils/text_storage.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/utils/universal_image_interceptor.py +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai.egg-info/dependency_links.txt +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai.egg-info/requires.txt +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai.egg-info/top_level.txt +0 -0
- {lucidicai-1.2.22 → lucidicai-1.3.0}/setup.cfg +0 -0
|
@@ -65,7 +65,7 @@ LUCIDIC_AGENT_ID=your_agent_id # Required: Your agent identifier
|
|
|
65
65
|
```python
|
|
66
66
|
lai.init(
|
|
67
67
|
session_name="My Session", # Required: Name for this session
|
|
68
|
-
|
|
68
|
+
api_key="...", # Optional: Override env var
|
|
69
69
|
agent_id="...", # Optional: Override env var
|
|
70
70
|
providers=["openai", "anthropic"], # Optional: LLM providers to track
|
|
71
71
|
task="Process customer request", # Optional: High-level task description
|
|
@@ -111,7 +111,7 @@ __all__ = [
|
|
|
111
111
|
def init(
|
|
112
112
|
session_name: Optional[str] = None,
|
|
113
113
|
session_id: Optional[str] = None,
|
|
114
|
-
|
|
114
|
+
api_key: Optional[str] = None,
|
|
115
115
|
agent_id: Optional[str] = None,
|
|
116
116
|
task: Optional[str] = None,
|
|
117
117
|
providers: Optional[List[ProviderType]] = [],
|
|
@@ -128,7 +128,7 @@ def init(
|
|
|
128
128
|
Args:
|
|
129
129
|
session_name: The display name of the session.
|
|
130
130
|
session_id: Custom ID of the session. If not provided, a random ID will be generated.
|
|
131
|
-
|
|
131
|
+
api_key: API key for authentication. If not provided, will use the LUCIDIC_API_KEY environment variable.
|
|
132
132
|
agent_id: Agent ID. If not provided, will use the LUCIDIC_AGENT_ID environment variable.
|
|
133
133
|
task: Task description.
|
|
134
134
|
providers: List of provider types ("openai", "anthropic", "langchain", "pydantic_ai").
|
|
@@ -142,27 +142,29 @@ def init(
|
|
|
142
142
|
InvalidOperationError: If the client is already initialized.
|
|
143
143
|
APIKeyVerificationError: If the API key is invalid.
|
|
144
144
|
"""
|
|
145
|
-
|
|
146
|
-
lucidic_api_key = os.getenv("LUCIDIC_API_KEY", None)
|
|
147
|
-
if lucidic_api_key is None:
|
|
148
|
-
raise APIKeyVerificationError("Make sure to either pass your API key into lai.init() or set the LUCIDIC_API_KEY environment variable.")
|
|
149
|
-
if agent_id is None:
|
|
150
|
-
agent_id = os.getenv("LUCIDIC_AGENT_ID", None)
|
|
151
|
-
if agent_id is None:
|
|
152
|
-
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.")
|
|
153
|
-
|
|
145
|
+
|
|
154
146
|
# get current client which will be NullClient if never lai is never initialized
|
|
155
147
|
client = Client()
|
|
156
|
-
#
|
|
148
|
+
# if not yet initialized or still the NullClient -> creaet a real client when init is called
|
|
157
149
|
if not getattr(client, 'initialized', False):
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
150
|
+
if api_key is None:
|
|
151
|
+
api_key = os.getenv("LUCIDIC_API_KEY", None)
|
|
152
|
+
if api_key is None:
|
|
153
|
+
raise APIKeyVerificationError("Make sure to either pass your API key into lai.init() or set the LUCIDIC_API_KEY environment variable.")
|
|
154
|
+
if agent_id is None:
|
|
155
|
+
agent_id = os.getenv("LUCIDIC_AGENT_ID", None)
|
|
156
|
+
if agent_id is None:
|
|
157
|
+
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.")
|
|
158
|
+
client = Client(api_key=api_key, agent_id=agent_id)
|
|
159
|
+
else:
|
|
160
|
+
# Already initialized, this is a re-init
|
|
161
|
+
api_key = api_key or os.getenv("LUCIDIC_API_KEY", None)
|
|
162
|
+
agent_id = agent_id or os.getenv("LUCIDIC_AGENT_ID", None)
|
|
163
|
+
client.agent_id = agent_id
|
|
164
|
+
if api_key is not None and agent_id is not None and (api_key != client.api_key or agent_id != client.agent_id):
|
|
165
|
+
client.set_api_key(api_key)
|
|
166
|
+
client.agent_id = agent_id
|
|
167
|
+
|
|
166
168
|
|
|
167
169
|
# Handle auto_end with environment variable support
|
|
168
170
|
if auto_end is None:
|
|
@@ -170,14 +172,14 @@ def init(
|
|
|
170
172
|
|
|
171
173
|
# Set up providers
|
|
172
174
|
_setup_providers(client, providers)
|
|
173
|
-
|
|
175
|
+
real_session_id = client.init_session(
|
|
174
176
|
session_name=session_name,
|
|
175
177
|
mass_sim_id=mass_sim_id,
|
|
176
178
|
task=task,
|
|
177
179
|
rubrics=rubrics,
|
|
178
180
|
tags=tags,
|
|
179
181
|
production_monitoring=production_monitoring,
|
|
180
|
-
|
|
182
|
+
session_id=session_id,
|
|
181
183
|
)
|
|
182
184
|
if masking_function:
|
|
183
185
|
client.masking_function = masking_function
|
|
@@ -186,20 +188,20 @@ def init(
|
|
|
186
188
|
client.auto_end = auto_end
|
|
187
189
|
|
|
188
190
|
logger.info("Session initialized successfully")
|
|
189
|
-
return
|
|
191
|
+
return real_session_id
|
|
190
192
|
|
|
191
193
|
|
|
192
194
|
def continue_session(
|
|
193
195
|
session_id: str,
|
|
194
|
-
|
|
196
|
+
api_key: Optional[str] = None,
|
|
195
197
|
agent_id: Optional[str] = None,
|
|
196
198
|
providers: Optional[List[ProviderType]] = [],
|
|
197
199
|
masking_function = None,
|
|
198
200
|
auto_end: Optional[bool] = True,
|
|
199
201
|
):
|
|
200
|
-
if
|
|
201
|
-
|
|
202
|
-
if
|
|
202
|
+
if api_key is None:
|
|
203
|
+
api_key = os.getenv("LUCIDIC_API_KEY", None)
|
|
204
|
+
if api_key is None:
|
|
203
205
|
raise APIKeyVerificationError("Make sure to either pass your API key into lai.init() or set the LUCIDIC_API_KEY environment variable.")
|
|
204
206
|
if agent_id is None:
|
|
205
207
|
agent_id = os.getenv("LUCIDIC_AGENT_ID", None)
|
|
@@ -211,7 +213,7 @@ def continue_session(
|
|
|
211
213
|
raise InvalidOperationError("[Lucidic] Session already in progress. Please call lai.end_session() or lai.reset_sdk() first.")
|
|
212
214
|
# if not yet initialized or still the NullClient -> create a real client when init is called
|
|
213
215
|
if not getattr(client, 'initialized', False):
|
|
214
|
-
client = Client(
|
|
216
|
+
client = Client(api_key=api_key, agent_id=agent_id)
|
|
215
217
|
|
|
216
218
|
# Handle auto_end with environment variable support
|
|
217
219
|
if auto_end is None:
|
|
@@ -284,8 +286,10 @@ def end_session(
|
|
|
284
286
|
|
|
285
287
|
def reset_sdk() -> None:
|
|
286
288
|
"""
|
|
287
|
-
Reset the SDK.
|
|
289
|
+
DEPRECATED: Reset the SDK.
|
|
288
290
|
"""
|
|
291
|
+
return
|
|
292
|
+
|
|
289
293
|
client = Client()
|
|
290
294
|
if not client.initialized:
|
|
291
295
|
return
|
|
@@ -342,7 +346,7 @@ signal.signal(signal.SIGTERM, _signal_handler)
|
|
|
342
346
|
def create_mass_sim(
|
|
343
347
|
mass_sim_name: str,
|
|
344
348
|
total_num_sessions: int,
|
|
345
|
-
|
|
349
|
+
api_key: Optional[str] = None,
|
|
346
350
|
agent_id: Optional[str] = None,
|
|
347
351
|
task: Optional[str] = None,
|
|
348
352
|
tags: Optional[list] = None
|
|
@@ -353,7 +357,7 @@ def create_mass_sim(
|
|
|
353
357
|
Args:
|
|
354
358
|
mass_sim_name: Name of the mass simulation.
|
|
355
359
|
total_num_sessions: Total intended number of sessions. More sessions can be added later.
|
|
356
|
-
|
|
360
|
+
api_key: API key for authentication. If not provided, will use the LUCIDIC_API_KEY environment variable.
|
|
357
361
|
agent_id: Agent ID. If not provided, will use the LUCIDIC_AGENT_ID environment variable.
|
|
358
362
|
task: Task description.
|
|
359
363
|
tags: Tags for the mass simulation.
|
|
@@ -361,9 +365,9 @@ def create_mass_sim(
|
|
|
361
365
|
Returns:
|
|
362
366
|
mass_sim_id: ID of the created mass simulation. Pass this to lai.init() to create a new session in the mass sim.
|
|
363
367
|
"""
|
|
364
|
-
if
|
|
365
|
-
|
|
366
|
-
if
|
|
368
|
+
if api_key is None:
|
|
369
|
+
api_key = os.getenv("LUCIDIC_API_KEY", None)
|
|
370
|
+
if api_key is None:
|
|
367
371
|
raise APIKeyVerificationError("Make sure to either pass your API key into lai.init() or set the LUCIDIC_API_KEY environment variable.")
|
|
368
372
|
if agent_id is None:
|
|
369
373
|
agent_id = os.getenv("LUCIDIC_AGENT_ID", None)
|
|
@@ -373,7 +377,7 @@ def create_mass_sim(
|
|
|
373
377
|
client = Client()
|
|
374
378
|
except LucidicNotInitializedError:
|
|
375
379
|
client = Client( # TODO: fail hard if incorrect API key or agent ID provided and wrong, fail silently if not provided
|
|
376
|
-
|
|
380
|
+
api_key=api_key,
|
|
377
381
|
agent_id=agent_id,
|
|
378
382
|
)
|
|
379
383
|
mass_sim_id = client.init_mass_sim(mass_sim_name=mass_sim_name, total_num_sims=total_num_sessions, task=task, tags=tags) # TODO: change total_num_sims to total_num_sessions everywhere
|
|
@@ -13,7 +13,7 @@ from .errors import APIKeyVerificationError, InvalidOperationError, LucidicNotIn
|
|
|
13
13
|
from .telemetry.base_provider import BaseProvider
|
|
14
14
|
from .session import Session
|
|
15
15
|
from .singleton import singleton, clear_singletons
|
|
16
|
-
|
|
16
|
+
from .lru import LRUCache
|
|
17
17
|
|
|
18
18
|
NETWORK_RETRIES = 3
|
|
19
19
|
|
|
@@ -22,14 +22,16 @@ NETWORK_RETRIES = 3
|
|
|
22
22
|
class Client:
|
|
23
23
|
def __init__(
|
|
24
24
|
self,
|
|
25
|
-
|
|
25
|
+
api_key: str,
|
|
26
26
|
agent_id: str,
|
|
27
27
|
):
|
|
28
28
|
self.base_url = "https://analytics.lucidic.ai/api" if not (os.getenv("LUCIDIC_DEBUG", 'False') == 'True') else "http://localhost:8000/api"
|
|
29
29
|
self.initialized = False
|
|
30
30
|
self.session = None
|
|
31
|
+
self.previous_sessions = LRUCache(500) # For LRU cache of previously initialized sessions
|
|
32
|
+
self.custom_session_id_translations = LRUCache(500) # For translations of custom session IDs to real session IDs
|
|
31
33
|
self.providers = []
|
|
32
|
-
self.api_key =
|
|
34
|
+
self.api_key = api_key
|
|
33
35
|
self.agent_id = agent_id
|
|
34
36
|
self.masking_function = None
|
|
35
37
|
self.auto_end = False # Default to False until explicitly set during init
|
|
@@ -42,13 +44,17 @@ class Client:
|
|
|
42
44
|
)
|
|
43
45
|
adapter = HTTPAdapter(max_retries=retry_cfg, pool_connections=20, pool_maxsize=100)
|
|
44
46
|
self.request_session.mount("https://", adapter)
|
|
45
|
-
self.
|
|
47
|
+
self.set_api_key(api_key)
|
|
46
48
|
self.prompts = dict()
|
|
49
|
+
|
|
50
|
+
def set_api_key(self, api_key: str):
|
|
51
|
+
self.api_key = api_key
|
|
52
|
+
self.request_session.headers.update({"Authorization": f"Api-Key {self.api_key}", "User-Agent": "lucidic-sdk/1.1"})
|
|
47
53
|
try:
|
|
48
|
-
self.verify_api_key(self.base_url,
|
|
54
|
+
self.verify_api_key(self.base_url, api_key)
|
|
49
55
|
except APIKeyVerificationError:
|
|
50
56
|
raise APIKeyVerificationError("Invalid API Key")
|
|
51
|
-
|
|
57
|
+
|
|
52
58
|
def clear(self):
|
|
53
59
|
self.undo_overrides()
|
|
54
60
|
clear_singletons()
|
|
@@ -69,7 +75,7 @@ class Client:
|
|
|
69
75
|
def undo_overrides(self):
|
|
70
76
|
for provider in self.providers:
|
|
71
77
|
provider.undo_override()
|
|
72
|
-
|
|
78
|
+
|
|
73
79
|
def init_session(
|
|
74
80
|
self,
|
|
75
81
|
session_name: str,
|
|
@@ -78,30 +84,69 @@ class Client:
|
|
|
78
84
|
rubrics: Optional[list] = None,
|
|
79
85
|
tags: Optional[list] = None,
|
|
80
86
|
production_monitoring: Optional[bool] = False,
|
|
81
|
-
|
|
87
|
+
session_id: Optional[str] = None,
|
|
82
88
|
) -> None:
|
|
89
|
+
if session_id:
|
|
90
|
+
# Check if it's a known session ID, maybe custom and maybe real
|
|
91
|
+
if session_id in self.custom_session_id_translations:
|
|
92
|
+
session_id = self.custom_session_id_translations[session_id]
|
|
93
|
+
# Check if it's the same as the current session
|
|
94
|
+
if self.session and self.session.session_id == session_id:
|
|
95
|
+
return self.session.session_id
|
|
96
|
+
# Check if it's a previous session that we have saved
|
|
97
|
+
if session_id in self.previous_sessions:
|
|
98
|
+
if self.session:
|
|
99
|
+
self.previous_sessions[self.session.session_id] = self.session
|
|
100
|
+
self.session = self.previous_sessions.pop(session_id) # Remove from previous sessions because it's now the current session
|
|
101
|
+
return self.session.session_id
|
|
102
|
+
|
|
103
|
+
# Either there's no session ID, or we don't know about the old session
|
|
104
|
+
# We need to go to the backend in both cases
|
|
105
|
+
request_data = {
|
|
106
|
+
"agent_id": self.agent_id,
|
|
107
|
+
"session_name": session_name,
|
|
108
|
+
"task": task,
|
|
109
|
+
"mass_sim_id": mass_sim_id,
|
|
110
|
+
"rubrics": rubrics,
|
|
111
|
+
"tags": tags,
|
|
112
|
+
"session_id": session_id
|
|
113
|
+
}
|
|
114
|
+
data = self.make_request('initsession', 'POST', request_data)
|
|
115
|
+
real_session_id = data["session_id"]
|
|
116
|
+
if session_id and session_id != real_session_id:
|
|
117
|
+
self.custom_session_id_translations[session_id] = real_session_id
|
|
118
|
+
|
|
119
|
+
if self.session:
|
|
120
|
+
self.previous_sessions[self.session.session_id] = self.session
|
|
121
|
+
|
|
83
122
|
self.session = Session(
|
|
84
123
|
agent_id=self.agent_id,
|
|
124
|
+
session_id=real_session_id,
|
|
85
125
|
session_name=session_name,
|
|
86
126
|
mass_sim_id=mass_sim_id,
|
|
87
127
|
task=task,
|
|
88
128
|
rubrics=rubrics,
|
|
89
129
|
tags=tags,
|
|
90
|
-
production_monitoring=production_monitoring,
|
|
91
|
-
custom_session_id=custom_session_id
|
|
92
130
|
)
|
|
93
131
|
self.initialized = True
|
|
94
132
|
return self.session.session_id
|
|
95
133
|
|
|
96
134
|
def continue_session(self, session_id: str):
|
|
135
|
+
if session_id in self.custom_session_id_translations:
|
|
136
|
+
session_id = self.custom_session_id_translations[session_id]
|
|
137
|
+
if self.session and self.session.session_id == session_id:
|
|
138
|
+
return self.session.session_id
|
|
139
|
+
if self.session:
|
|
140
|
+
self.previous_sessions[self.session.session_id] = self.session
|
|
141
|
+
data = self.make_request('continuesession', 'POST', {"session_id": session_id})
|
|
142
|
+
real_session_id = data["session_id"]
|
|
143
|
+
if session_id != real_session_id:
|
|
144
|
+
self.custom_session_id_translations[session_id] = real_session_id
|
|
97
145
|
self.session = Session(
|
|
98
146
|
agent_id=self.agent_id,
|
|
99
|
-
session_id=
|
|
147
|
+
session_id=real_session_id
|
|
100
148
|
)
|
|
101
|
-
|
|
102
|
-
# Custom session ID provided
|
|
103
|
-
self.session.custom_session_id = session_id
|
|
104
|
-
self.initialized = True
|
|
149
|
+
logger.info(f"Session {data.get('session_name', '')} continuing...")
|
|
105
150
|
return self.session.session_id
|
|
106
151
|
|
|
107
152
|
def init_mass_sim(self, **kwargs) -> str:
|
|
@@ -131,6 +176,7 @@ class Client:
|
|
|
131
176
|
return prompt
|
|
132
177
|
|
|
133
178
|
def make_request(self, endpoint, method, data):
|
|
179
|
+
print(f"Making request to {self.base_url}/{endpoint} with method {method} and data {data}")
|
|
134
180
|
http_methods = {
|
|
135
181
|
"GET": lambda data: self.request_session.get(f"{self.base_url}/{endpoint}", params=data),
|
|
136
182
|
"POST": lambda data: self.request_session.post(f"{self.base_url}/{endpoint}", json=data),
|
|
@@ -16,7 +16,6 @@ class Event:
|
|
|
16
16
|
self.is_finished = False
|
|
17
17
|
self.init_event(**kwargs)
|
|
18
18
|
|
|
19
|
-
# TODO: this is really bad, clean this up later
|
|
20
19
|
def init_event(self, **kwargs) -> None:
|
|
21
20
|
from .client import Client
|
|
22
21
|
request_data = self._build_request_data(**kwargs)
|
|
@@ -41,7 +40,7 @@ class Event:
|
|
|
41
40
|
|
|
42
41
|
def _build_request_data(self, **kwargs) -> dict:
|
|
43
42
|
from .client import Client
|
|
44
|
-
num_new_screenshots = len(kwargs.get("screenshots", []))
|
|
43
|
+
num_new_screenshots = len(kwargs.get("screenshots", []) or [])
|
|
45
44
|
return {
|
|
46
45
|
"description": Client().mask(kwargs.get("description", None)),
|
|
47
46
|
"result": Client().mask(kwargs.get("result", None)),
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from collections import OrderedDict
|
|
2
|
+
|
|
3
|
+
class LRUCache(OrderedDict):
|
|
4
|
+
def __init__(self, capacity: int):
|
|
5
|
+
super().__init__()
|
|
6
|
+
self.capacity = capacity
|
|
7
|
+
|
|
8
|
+
def __getitem__(self, key):
|
|
9
|
+
if key not in self:
|
|
10
|
+
raise KeyError(key)
|
|
11
|
+
self.move_to_end(key) # Mark as recently used
|
|
12
|
+
return super().__getitem__(key)
|
|
13
|
+
|
|
14
|
+
def __setitem__(self, key, value):
|
|
15
|
+
if key in self:
|
|
16
|
+
self.move_to_end(key) # Update position
|
|
17
|
+
super().__setitem__(key, value)
|
|
18
|
+
if len(self) > self.capacity:
|
|
19
|
+
self.popitem(last=False) # Evict least recently used item
|
|
@@ -15,11 +15,12 @@ logger = logging.getLogger("Lucidic")
|
|
|
15
15
|
class Session:
|
|
16
16
|
def __init__(
|
|
17
17
|
self,
|
|
18
|
-
agent_id: str,
|
|
18
|
+
agent_id: str,
|
|
19
|
+
session_id = None,
|
|
19
20
|
**kwargs
|
|
20
21
|
):
|
|
21
22
|
self.agent_id = agent_id
|
|
22
|
-
self.session_id =
|
|
23
|
+
self.session_id = session_id
|
|
23
24
|
self.step_history = dict()
|
|
24
25
|
self._active_step: Optional[str] = None # Step ID, not Step object
|
|
25
26
|
self.event_history = dict()
|
|
@@ -30,33 +31,6 @@ class Session:
|
|
|
30
31
|
self.session_eval = None
|
|
31
32
|
self.session_eval_reason = None
|
|
32
33
|
self.has_gif = None
|
|
33
|
-
if kwargs.get("session_id", None) is None: # The kwarg, not the attribute
|
|
34
|
-
self.init_session(**kwargs)
|
|
35
|
-
else:
|
|
36
|
-
self.continue_session(kwargs["session_id"])
|
|
37
|
-
|
|
38
|
-
def init_session(self, **kwargs) -> None:
|
|
39
|
-
from .client import Client
|
|
40
|
-
request_data = {
|
|
41
|
-
"agent_id": self.agent_id,
|
|
42
|
-
"session_name": kwargs.get("session_name", None),
|
|
43
|
-
"task": kwargs.get("task", None),
|
|
44
|
-
"mass_sim_id": kwargs.get("mass_sim_id", None),
|
|
45
|
-
"rubrics": kwargs.get("rubrics", None),
|
|
46
|
-
"tags": kwargs.get("tags", None),
|
|
47
|
-
"production_monitoring": kwargs.get("production_monitoring", False),
|
|
48
|
-
"custom_session_id": kwargs.get("custom_session_id", None)
|
|
49
|
-
}
|
|
50
|
-
data = Client().make_request('initsession', 'POST', request_data)
|
|
51
|
-
self.session_id = data["session_id"]
|
|
52
|
-
|
|
53
|
-
def continue_session(self, session_id: str) -> None:
|
|
54
|
-
from .client import Client
|
|
55
|
-
self.session_id = session_id
|
|
56
|
-
data = Client().make_request('continuesession', 'POST', {"session_id": session_id})
|
|
57
|
-
self.session_id = data["session_id"]
|
|
58
|
-
logger.info(f"Session {data['session_name']} continuing...")
|
|
59
|
-
return self.session_id
|
|
60
34
|
|
|
61
35
|
@property
|
|
62
36
|
def active_step(self) -> Optional[Step]:
|
|
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
|
{lucidicai-1.2.22 → lucidicai-1.3.0}/lucidicai/telemetry/utils/universal_image_interceptor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|