alita-sdk 0.3.465__py3-none-any.whl → 0.3.497__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.
Potentially problematic release.
This version of alita-sdk might be problematic. Click here for more details.
- alita_sdk/cli/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +83 -1
- alita_sdk/cli/agent_loader.py +22 -4
- alita_sdk/cli/agent_ui.py +13 -3
- alita_sdk/cli/agents.py +1876 -186
- alita_sdk/cli/callbacks.py +96 -25
- alita_sdk/cli/cli.py +10 -1
- alita_sdk/cli/config.py +151 -9
- alita_sdk/cli/context/__init__.py +30 -0
- alita_sdk/cli/context/cleanup.py +198 -0
- alita_sdk/cli/context/manager.py +731 -0
- alita_sdk/cli/context/message.py +285 -0
- alita_sdk/cli/context/strategies.py +289 -0
- alita_sdk/cli/context/token_estimation.py +127 -0
- alita_sdk/cli/input_handler.py +167 -4
- alita_sdk/cli/inventory.py +1256 -0
- alita_sdk/cli/toolkit.py +14 -17
- alita_sdk/cli/toolkit_loader.py +35 -5
- alita_sdk/cli/tools/__init__.py +8 -1
- alita_sdk/cli/tools/filesystem.py +910 -64
- alita_sdk/cli/tools/planning.py +143 -157
- alita_sdk/cli/tools/terminal.py +154 -20
- alita_sdk/community/__init__.py +64 -8
- alita_sdk/community/inventory/__init__.py +224 -0
- alita_sdk/community/inventory/config.py +257 -0
- alita_sdk/community/inventory/enrichment.py +2137 -0
- alita_sdk/community/inventory/extractors.py +1469 -0
- alita_sdk/community/inventory/ingestion.py +3172 -0
- alita_sdk/community/inventory/knowledge_graph.py +1457 -0
- alita_sdk/community/inventory/parsers/__init__.py +218 -0
- alita_sdk/community/inventory/parsers/base.py +295 -0
- alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
- alita_sdk/community/inventory/parsers/go_parser.py +851 -0
- alita_sdk/community/inventory/parsers/html_parser.py +389 -0
- alita_sdk/community/inventory/parsers/java_parser.py +593 -0
- alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
- alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
- alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
- alita_sdk/community/inventory/parsers/python_parser.py +604 -0
- alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
- alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
- alita_sdk/community/inventory/parsers/text_parser.py +322 -0
- alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
- alita_sdk/community/inventory/patterns/__init__.py +61 -0
- alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
- alita_sdk/community/inventory/patterns/loader.py +348 -0
- alita_sdk/community/inventory/patterns/registry.py +198 -0
- alita_sdk/community/inventory/presets.py +535 -0
- alita_sdk/community/inventory/retrieval.py +1403 -0
- alita_sdk/community/inventory/toolkit.py +169 -0
- alita_sdk/community/inventory/visualize.py +1370 -0
- alita_sdk/configurations/bitbucket.py +0 -3
- alita_sdk/runtime/clients/client.py +108 -31
- alita_sdk/runtime/langchain/assistant.py +4 -2
- alita_sdk/runtime/langchain/constants.py +3 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
- alita_sdk/runtime/langchain/document_loaders/constants.py +10 -6
- alita_sdk/runtime/langchain/langraph_agent.py +123 -31
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/toolkits/__init__.py +2 -0
- alita_sdk/runtime/toolkits/application.py +1 -1
- alita_sdk/runtime/toolkits/mcp.py +107 -91
- alita_sdk/runtime/toolkits/planning.py +173 -0
- alita_sdk/runtime/toolkits/tools.py +59 -7
- alita_sdk/runtime/tools/artifact.py +46 -17
- alita_sdk/runtime/tools/function.py +2 -1
- alita_sdk/runtime/tools/llm.py +320 -32
- alita_sdk/runtime/tools/mcp_remote_tool.py +23 -7
- alita_sdk/runtime/tools/planning/__init__.py +36 -0
- alita_sdk/runtime/tools/planning/models.py +246 -0
- alita_sdk/runtime/tools/planning/wrapper.py +607 -0
- alita_sdk/runtime/tools/vectorstore_base.py +44 -9
- alita_sdk/runtime/utils/AlitaCallback.py +106 -20
- alita_sdk/runtime/utils/mcp_client.py +465 -0
- alita_sdk/runtime/utils/mcp_oauth.py +80 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/streamlit.py +6 -10
- alita_sdk/runtime/utils/toolkit_utils.py +14 -5
- alita_sdk/tools/__init__.py +54 -27
- alita_sdk/tools/ado/repos/repos_wrapper.py +1 -2
- alita_sdk/tools/base_indexer_toolkit.py +99 -20
- alita_sdk/tools/bitbucket/__init__.py +2 -2
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code_indexer_toolkit.py +55 -22
- alita_sdk/tools/confluence/api_wrapper.py +63 -14
- alita_sdk/tools/elitea_base.py +86 -21
- alita_sdk/tools/jira/__init__.py +1 -1
- alita_sdk/tools/jira/api_wrapper.py +91 -40
- alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
- alita_sdk/tools/qtest/__init__.py +1 -1
- alita_sdk/tools/sharepoint/api_wrapper.py +2 -2
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +17 -13
- alita_sdk/tools/zephyr_essential/api_wrapper.py +12 -13
- {alita_sdk-0.3.465.dist-info → alita_sdk-0.3.497.dist-info}/METADATA +2 -1
- {alita_sdk-0.3.465.dist-info → alita_sdk-0.3.497.dist-info}/RECORD +103 -61
- {alita_sdk-0.3.465.dist-info → alita_sdk-0.3.497.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.465.dist-info → alita_sdk-0.3.497.dist-info}/entry_points.txt +0 -0
- {alita_sdk-0.3.465.dist-info → alita_sdk-0.3.497.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.465.dist-info → alita_sdk-0.3.497.dist-info}/top_level.txt +0 -0
|
@@ -155,15 +155,45 @@ class VectorStoreWrapperBase(BaseToolApiWrapper):
|
|
|
155
155
|
if values.get('alita') and values.get('embedding_model'):
|
|
156
156
|
values['embeddings'] = values.get('alita').get_embeddings(values.get('embedding_model'))
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# Initialize the new vector adapter
|
|
161
|
-
values['vector_adapter'] = VectorStoreAdapterFactory.create_adapter(values['vectorstore_type'])
|
|
162
|
-
logger.debug(f"Vectorstore wrapper initialized: {values}")
|
|
158
|
+
# Lazy initialization: vectorstore and vector_adapter are initialized on-demand
|
|
159
|
+
# This prevents errors when using non-index tools with broken/missing vector DB
|
|
163
160
|
return values
|
|
164
161
|
|
|
162
|
+
def _ensure_vectorstore_initialized(self):
|
|
163
|
+
"""Lazily initialize vectorstore and vector_adapter when needed for index operations."""
|
|
164
|
+
if self.vectorstore is None:
|
|
165
|
+
if not self.vectorstore_type or not self.vectorstore_params:
|
|
166
|
+
raise ToolException(
|
|
167
|
+
"Vector store is not configured. "
|
|
168
|
+
"Please ensure embedding_model and pgvector_configuration are provided."
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
from ..langchain.interfaces.llm_processor import get_vectorstore
|
|
172
|
+
try:
|
|
173
|
+
self.vectorstore = get_vectorstore(
|
|
174
|
+
self.vectorstore_type,
|
|
175
|
+
self.vectorstore_params,
|
|
176
|
+
embedding_func=self.embeddings
|
|
177
|
+
)
|
|
178
|
+
logger.debug(f"Vectorstore initialized: {self.vectorstore_type}")
|
|
179
|
+
except Exception as e:
|
|
180
|
+
raise ToolException(
|
|
181
|
+
f"Failed to initialize vector store: {str(e)}. "
|
|
182
|
+
"Check your vector database configuration and connection."
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
if self.vector_adapter is None:
|
|
186
|
+
try:
|
|
187
|
+
self.vector_adapter = VectorStoreAdapterFactory.create_adapter(self.vectorstore_type)
|
|
188
|
+
logger.debug(f"Vector adapter initialized: {self.vectorstore_type}")
|
|
189
|
+
except Exception as e:
|
|
190
|
+
raise ToolException(
|
|
191
|
+
f"Failed to initialize vector adapter: {str(e)}"
|
|
192
|
+
)
|
|
193
|
+
|
|
165
194
|
def _init_pg_helper(self, language='english'):
|
|
166
195
|
"""Initialize PGVector helper if needed and not already initialized"""
|
|
196
|
+
self._ensure_vectorstore_initialized()
|
|
167
197
|
if self.pg_helper is None and hasattr(self.vectorstore, 'connection_string') and hasattr(self.vectorstore, 'collection_name'):
|
|
168
198
|
try:
|
|
169
199
|
from .pgvector_search import PGVectorSearch
|
|
@@ -192,6 +222,7 @@ class VectorStoreWrapperBase(BaseToolApiWrapper):
|
|
|
192
222
|
Raises:
|
|
193
223
|
ToolException: When DataException occurs or other search errors
|
|
194
224
|
"""
|
|
225
|
+
self._ensure_vectorstore_initialized()
|
|
195
226
|
try:
|
|
196
227
|
return self.vectorstore.similarity_search_with_score(
|
|
197
228
|
query, filter=filter, k=k
|
|
@@ -210,19 +241,21 @@ class VectorStoreWrapperBase(BaseToolApiWrapper):
|
|
|
210
241
|
|
|
211
242
|
def list_collections(self) -> List[str]:
|
|
212
243
|
"""List all collections in the vectorstore."""
|
|
213
|
-
|
|
244
|
+
self._ensure_vectorstore_initialized()
|
|
214
245
|
collections = self.vector_adapter.list_collections(self)
|
|
215
246
|
if not collections:
|
|
216
247
|
return "No indexed collections"
|
|
217
248
|
return collections
|
|
218
249
|
|
|
219
250
|
def get_index_meta(self, index_name: str):
|
|
251
|
+
self._ensure_vectorstore_initialized()
|
|
220
252
|
index_metas = self.vector_adapter.get_index_meta(self, index_name)
|
|
221
253
|
if len(index_metas) > 1:
|
|
222
254
|
raise RuntimeError(f"Multiple index_meta documents found: {index_metas}")
|
|
223
255
|
return index_metas[0] if index_metas else None
|
|
224
256
|
|
|
225
257
|
def get_indexed_count(self, index_name: str) -> int:
|
|
258
|
+
self._ensure_vectorstore_initialized()
|
|
226
259
|
from sqlalchemy.orm import Session
|
|
227
260
|
from sqlalchemy import func, or_
|
|
228
261
|
|
|
@@ -237,15 +270,16 @@ class VectorStoreWrapperBase(BaseToolApiWrapper):
|
|
|
237
270
|
)
|
|
238
271
|
).count()
|
|
239
272
|
|
|
240
|
-
def _clean_collection(self, index_name: str = ''):
|
|
273
|
+
def _clean_collection(self, index_name: str = '', including_index_meta: bool = False):
|
|
241
274
|
"""
|
|
242
275
|
Clean the vectorstore collection by deleting all indexed data.
|
|
243
276
|
"""
|
|
277
|
+
self._ensure_vectorstore_initialized()
|
|
244
278
|
self._log_tool_event(
|
|
245
279
|
f"Cleaning collection '{self.dataset}'",
|
|
246
280
|
tool_name="_clean_collection"
|
|
247
281
|
)
|
|
248
|
-
self.vector_adapter.clean_collection(self, index_name)
|
|
282
|
+
self.vector_adapter.clean_collection(self, index_name, including_index_meta)
|
|
249
283
|
self._log_tool_event(
|
|
250
284
|
f"Collection '{self.dataset}' has been cleaned. ",
|
|
251
285
|
tool_name="_clean_collection"
|
|
@@ -259,6 +293,7 @@ class VectorStoreWrapperBase(BaseToolApiWrapper):
|
|
|
259
293
|
progress_step (int): Step for progress reporting, default is 20.
|
|
260
294
|
clean_index (bool): If True, clean the index before re-indexing all documents.
|
|
261
295
|
"""
|
|
296
|
+
self._ensure_vectorstore_initialized()
|
|
262
297
|
if clean_index:
|
|
263
298
|
self._clean_index(index_name)
|
|
264
299
|
|
|
@@ -268,7 +303,7 @@ class VectorStoreWrapperBase(BaseToolApiWrapper):
|
|
|
268
303
|
logger.info("Cleaning index before re-indexing all documents.")
|
|
269
304
|
self._log_tool_event("Cleaning index before re-indexing all documents. Previous index will be removed", tool_name="index_documents")
|
|
270
305
|
try:
|
|
271
|
-
self._clean_collection(index_name)
|
|
306
|
+
self._clean_collection(index_name, including_index_meta=False)
|
|
272
307
|
self._log_tool_event("Previous index has been removed",
|
|
273
308
|
tool_name="index_documents")
|
|
274
309
|
except Exception as e:
|
|
@@ -23,9 +23,45 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
23
23
|
self.tokens_out = 0
|
|
24
24
|
self.pending_llm_requests = defaultdict(int)
|
|
25
25
|
self.current_model_name = 'gpt-4'
|
|
26
|
+
self._event_queue = [] # Queue for events when context is unavailable
|
|
26
27
|
#
|
|
27
28
|
super().__init__()
|
|
28
29
|
|
|
30
|
+
def _has_streamlit_context(self) -> bool:
|
|
31
|
+
"""Check if Streamlit context is available in the current thread."""
|
|
32
|
+
try:
|
|
33
|
+
# Try to import streamlit runtime context checker
|
|
34
|
+
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
|
35
|
+
ctx = get_script_run_ctx()
|
|
36
|
+
return ctx is not None
|
|
37
|
+
except (ImportError, Exception) as e:
|
|
38
|
+
if self.debug:
|
|
39
|
+
log.debug(f"Streamlit context check failed: {e}")
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
def _safe_streamlit_call(self, func, *args, **kwargs):
|
|
43
|
+
"""Safely execute a Streamlit UI operation, handling missing context gracefully."""
|
|
44
|
+
if not self._has_streamlit_context():
|
|
45
|
+
func_name = getattr(func, '__name__', str(func))
|
|
46
|
+
if self.debug:
|
|
47
|
+
log.warning(f"Streamlit context not available for {func_name}, queueing event")
|
|
48
|
+
# Store the event for potential replay when context is available
|
|
49
|
+
self._event_queue.append({
|
|
50
|
+
'func': func_name,
|
|
51
|
+
'args': args,
|
|
52
|
+
'kwargs': kwargs,
|
|
53
|
+
'timestamp': datetime.now(tz=timezone.utc)
|
|
54
|
+
})
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
return func(*args, **kwargs)
|
|
59
|
+
except Exception as e:
|
|
60
|
+
func_name = getattr(func, '__name__', str(func))
|
|
61
|
+
# Handle any Streamlit-specific exceptions gracefully
|
|
62
|
+
log.warning(f"Streamlit operation {func_name} failed: {e}")
|
|
63
|
+
return None
|
|
64
|
+
|
|
29
65
|
#
|
|
30
66
|
# Chain
|
|
31
67
|
#
|
|
@@ -76,10 +112,14 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
76
112
|
json.dumps(payload, ensure_ascii=False, default=lambda o: str(o))
|
|
77
113
|
)
|
|
78
114
|
|
|
79
|
-
|
|
80
|
-
|
|
115
|
+
status_widget = self._safe_streamlit_call(
|
|
116
|
+
self.st.status,
|
|
117
|
+
f"Running {payload.get('tool_name')}...",
|
|
118
|
+
expanded=True
|
|
81
119
|
)
|
|
82
|
-
|
|
120
|
+
if status_widget:
|
|
121
|
+
self.callback_state[str(run_id)] = status_widget
|
|
122
|
+
self._safe_streamlit_call(status_widget.write, f"Tool inputs: {payload}")
|
|
83
123
|
|
|
84
124
|
def on_tool_start(self, *args, run_id: UUID, **kwargs):
|
|
85
125
|
""" Callback """
|
|
@@ -95,8 +135,15 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
95
135
|
"tool_inputs": kwargs.get('inputs')
|
|
96
136
|
}
|
|
97
137
|
payload = json.loads(json.dumps(payload, ensure_ascii=False, default=lambda o: str(o)))
|
|
98
|
-
|
|
99
|
-
|
|
138
|
+
|
|
139
|
+
status_widget = self._safe_streamlit_call(
|
|
140
|
+
self.st.status,
|
|
141
|
+
f"Running {tool_name}...",
|
|
142
|
+
expanded=True
|
|
143
|
+
)
|
|
144
|
+
if status_widget:
|
|
145
|
+
self.callback_state[tool_run_id] = status_widget
|
|
146
|
+
self._safe_streamlit_call(status_widget.write, f"Tool inputs: {kwargs.get('inputs')}")
|
|
100
147
|
|
|
101
148
|
def on_tool_end(self, *args, run_id: UUID, **kwargs):
|
|
102
149
|
""" Callback """
|
|
@@ -104,11 +151,16 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
104
151
|
log.info("on_tool_end(%s, %s)", args, kwargs)
|
|
105
152
|
tool_run_id = str(run_id)
|
|
106
153
|
tool_output = args[0]
|
|
107
|
-
if self.callback_state
|
|
108
|
-
self.callback_state[tool_run_id]
|
|
109
|
-
self.
|
|
154
|
+
if self.callback_state.get(tool_run_id):
|
|
155
|
+
status_widget = self.callback_state[tool_run_id]
|
|
156
|
+
self._safe_streamlit_call(status_widget.write, f"Tool output: {tool_output}")
|
|
157
|
+
self._safe_streamlit_call(
|
|
158
|
+
status_widget.update,
|
|
159
|
+
label=f"Completed {kwargs.get('name')}",
|
|
160
|
+
state="complete",
|
|
161
|
+
expanded=False
|
|
162
|
+
)
|
|
110
163
|
self.callback_state.pop(tool_run_id, None)
|
|
111
|
-
del self.callback_state[run_id]
|
|
112
164
|
|
|
113
165
|
def on_tool_error(self, *args, run_id: UUID, **kwargs):
|
|
114
166
|
""" Callback """
|
|
@@ -116,9 +168,19 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
116
168
|
log.info("on_tool_error(%s, %s)", args, kwargs)
|
|
117
169
|
tool_run_id = str(run_id)
|
|
118
170
|
tool_exception = args[0]
|
|
119
|
-
self.callback_state
|
|
120
|
-
|
|
121
|
-
|
|
171
|
+
if self.callback_state.get(tool_run_id):
|
|
172
|
+
status_widget = self.callback_state[tool_run_id]
|
|
173
|
+
self._safe_streamlit_call(
|
|
174
|
+
status_widget.write,
|
|
175
|
+
f"{traceback.format_exception(tool_exception)}"
|
|
176
|
+
)
|
|
177
|
+
self._safe_streamlit_call(
|
|
178
|
+
status_widget.update,
|
|
179
|
+
label=f"Error {kwargs.get('name')}",
|
|
180
|
+
state="error",
|
|
181
|
+
expanded=False
|
|
182
|
+
)
|
|
183
|
+
self.callback_state.pop(tool_run_id, None)
|
|
122
184
|
|
|
123
185
|
#
|
|
124
186
|
# Agent
|
|
@@ -156,8 +218,14 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
156
218
|
self.current_model_name = metadata.get('ls_model_name', self.current_model_name)
|
|
157
219
|
llm_run_id = str(run_id)
|
|
158
220
|
|
|
159
|
-
|
|
160
|
-
|
|
221
|
+
status_widget = self._safe_streamlit_call(
|
|
222
|
+
self.st.status,
|
|
223
|
+
f"Running LLM ...",
|
|
224
|
+
expanded=True
|
|
225
|
+
)
|
|
226
|
+
if status_widget:
|
|
227
|
+
self.callback_state[llm_run_id] = status_widget
|
|
228
|
+
self._safe_streamlit_call(status_widget.write, f"LLM inputs: {messages}")
|
|
161
229
|
|
|
162
230
|
def on_llm_start(self, *args, **kwargs):
|
|
163
231
|
""" Callback """
|
|
@@ -178,16 +246,27 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
178
246
|
content = None
|
|
179
247
|
if chunk:
|
|
180
248
|
content = chunk.text
|
|
181
|
-
|
|
249
|
+
|
|
250
|
+
llm_run_id = str(run_id)
|
|
251
|
+
if self.callback_state.get(llm_run_id):
|
|
252
|
+
status_widget = self.callback_state[llm_run_id]
|
|
253
|
+
self._safe_streamlit_call(status_widget.write, content)
|
|
182
254
|
|
|
183
255
|
def on_llm_error(self, *args, run_id: UUID, **kwargs):
|
|
184
256
|
""" Callback """
|
|
185
257
|
if self.debug:
|
|
186
258
|
log.error("on_llm_error(%s, %s)", args, kwargs)
|
|
187
259
|
llm_run_id = str(run_id)
|
|
188
|
-
self.callback_state
|
|
189
|
-
|
|
190
|
-
|
|
260
|
+
if self.callback_state.get(llm_run_id):
|
|
261
|
+
status_widget = self.callback_state[llm_run_id]
|
|
262
|
+
self._safe_streamlit_call(status_widget.write, f"on_llm_error({args}, {kwargs})")
|
|
263
|
+
self._safe_streamlit_call(
|
|
264
|
+
status_widget.update,
|
|
265
|
+
label=f"Error {kwargs.get('name')}",
|
|
266
|
+
state="error",
|
|
267
|
+
expanded=False
|
|
268
|
+
)
|
|
269
|
+
self.callback_state.pop(llm_run_id, None)
|
|
191
270
|
#
|
|
192
271
|
# exception = args[0]
|
|
193
272
|
# FIXME: should we emit an error here too?
|
|
@@ -205,5 +284,12 @@ class AlitaStreamlitCallback(BaseCallbackHandler):
|
|
|
205
284
|
if self.debug:
|
|
206
285
|
log.debug("on_llm_end(%s, %s)", response, kwargs)
|
|
207
286
|
llm_run_id = str(run_id)
|
|
208
|
-
self.callback_state
|
|
209
|
-
|
|
287
|
+
if self.callback_state.get(llm_run_id):
|
|
288
|
+
status_widget = self.callback_state[llm_run_id]
|
|
289
|
+
self._safe_streamlit_call(
|
|
290
|
+
status_widget.update,
|
|
291
|
+
label=f"Completed LLM call",
|
|
292
|
+
state="complete",
|
|
293
|
+
expanded=False
|
|
294
|
+
)
|
|
295
|
+
self.callback_state.pop(llm_run_id, None)
|