flowcept 0.8.10__py3-none-any.whl → 0.8.11__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.
Files changed (42) hide show
  1. flowcept/cli.py +210 -10
  2. flowcept/commons/daos/keyvalue_dao.py +19 -23
  3. flowcept/commons/daos/mq_dao/mq_dao_base.py +29 -29
  4. flowcept/commons/daos/mq_dao/mq_dao_kafka.py +4 -3
  5. flowcept/commons/daos/mq_dao/mq_dao_mofka.py +4 -0
  6. flowcept/commons/daos/mq_dao/mq_dao_redis.py +38 -5
  7. flowcept/commons/daos/redis_conn.py +47 -0
  8. flowcept/commons/flowcept_dataclasses/task_object.py +36 -8
  9. flowcept/commons/settings_factory.py +2 -4
  10. flowcept/commons/task_data_preprocess.py +200 -0
  11. flowcept/commons/utils.py +1 -1
  12. flowcept/configs.py +8 -4
  13. flowcept/flowcept_api/flowcept_controller.py +30 -13
  14. flowcept/flowceptor/adapters/agents/__init__.py +1 -0
  15. flowcept/flowceptor/adapters/agents/agents_utils.py +89 -0
  16. flowcept/flowceptor/adapters/agents/flowcept_agent.py +292 -0
  17. flowcept/flowceptor/adapters/agents/flowcept_llm_prov_capture.py +186 -0
  18. flowcept/flowceptor/adapters/agents/prompts.py +51 -0
  19. flowcept/flowceptor/adapters/base_interceptor.py +13 -6
  20. flowcept/flowceptor/adapters/brokers/__init__.py +1 -0
  21. flowcept/flowceptor/adapters/brokers/mqtt_interceptor.py +132 -0
  22. flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py +3 -3
  23. flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py +3 -3
  24. flowcept/flowceptor/consumers/agent/__init__.py +1 -0
  25. flowcept/flowceptor/consumers/agent/base_agent_context_manager.py +101 -0
  26. flowcept/flowceptor/consumers/agent/client_agent.py +48 -0
  27. flowcept/flowceptor/consumers/agent/flowcept_agent_context_manager.py +145 -0
  28. flowcept/flowceptor/consumers/agent/flowcept_qa_manager.py +112 -0
  29. flowcept/flowceptor/consumers/base_consumer.py +90 -0
  30. flowcept/flowceptor/consumers/document_inserter.py +135 -36
  31. flowcept/flowceptor/telemetry_capture.py +1 -1
  32. flowcept/instrumentation/task_capture.py +8 -2
  33. flowcept/version.py +1 -1
  34. {flowcept-0.8.10.dist-info → flowcept-0.8.11.dist-info}/METADATA +10 -1
  35. {flowcept-0.8.10.dist-info → flowcept-0.8.11.dist-info}/RECORD +39 -27
  36. resources/sample_settings.yaml +37 -13
  37. flowcept/flowceptor/adapters/zambeze/__init__.py +0 -1
  38. flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py +0 -41
  39. flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py +0 -102
  40. {flowcept-0.8.10.dist-info → flowcept-0.8.11.dist-info}/WHEEL +0 -0
  41. {flowcept-0.8.10.dist-info → flowcept-0.8.11.dist-info}/entry_points.txt +0 -0
  42. {flowcept-0.8.10.dist-info → flowcept-0.8.11.dist-info}/licenses/LICENSE +0 -0
@@ -2,11 +2,12 @@
2
2
 
3
3
  from threading import Thread
4
4
  from time import time, sleep
5
- from typing import Dict
5
+ from typing import Dict, Callable, Tuple
6
6
  from uuid import uuid4
7
7
 
8
+ from flowcept.commons.task_data_preprocess import summarize_telemetry, tag_critical_task
9
+ from flowcept.flowceptor.consumers.base_consumer import BaseConsumer
8
10
  from flowcept.commons.autoflush_buffer import AutoflushBuffer
9
- from flowcept.commons.daos.mq_dao.mq_dao_base import MQDao
10
11
  from flowcept.commons.flowcept_dataclasses.task_object import TaskObject
11
12
  from flowcept.commons.flowcept_dataclasses.workflow_object import (
12
13
  WorkflowObject,
@@ -30,8 +31,18 @@ from flowcept.flowceptor.consumers.consumer_utils import (
30
31
  )
31
32
 
32
33
 
33
- class DocumentInserter:
34
- """Document class."""
34
+ class DocumentInserter(BaseConsumer):
35
+ """
36
+ DocumentInserter is a message consumer in Flowcept.
37
+
38
+ It handles messages related to tasks, workflows, and control signals, processes them
39
+ (e.g., adds metadata, sanitizes fields), and then inserts them into one or more configured
40
+ document databases (e.g., MongoDB, LMDB). It buffers incoming messages to reduce insertion
41
+ overhead and supports both time-based and size-based flushing.
42
+
43
+ The inserter is intended to run in a thread or process alongside other Flowcept consumers,
44
+ ensuring provenance data is persisted reliably and in a structured format.
45
+ """
35
46
 
36
47
  DECODER = GenericJSONDecoder if JSON_SERIALIZER == "complex" else None
37
48
 
@@ -52,8 +63,8 @@ class DocumentInserter:
52
63
  check_safe_stops=True,
53
64
  bundle_exec_id=None,
54
65
  ):
55
- self._mq_dao = MQDao.build()
56
66
  self._doc_daos = []
67
+ self.logger = FlowceptLogger()
57
68
  if MONGO_ENABLED:
58
69
  from flowcept.commons.daos.docdb_dao.mongodb_dao import MongoDBDAO
59
70
 
@@ -62,8 +73,13 @@ class DocumentInserter:
62
73
  from flowcept.commons.daos.docdb_dao.lmdb_dao import LMDBDAO
63
74
 
64
75
  self._doc_daos.append(LMDBDAO())
76
+ self._should_start = True
77
+ if not len(self._doc_daos):
78
+ self._should_start = False
79
+ return
80
+
81
+ super().__init__()
65
82
  self._previous_time = time()
66
- self.logger = FlowceptLogger()
67
83
  self._main_thread: Thread = None
68
84
  self._curr_db_buffer_size = DB_BUFFER_SIZE
69
85
  self._bundle_exec_id = bundle_exec_id
@@ -77,7 +93,18 @@ class DocumentInserter:
77
93
 
78
94
  @staticmethod
79
95
  def flush_function(buffer, doc_daos, logger):
80
- """Flush it."""
96
+ """
97
+ Flush the buffer contents to all configured document databases.
98
+
99
+ Parameters
100
+ ----------
101
+ buffer : list
102
+ List of messages to be flushed to the databases.
103
+ doc_daos : list
104
+ List of DAO instances to insert data into (e.g., MongoDBDAO, LMDBDAO).
105
+ logger : FlowceptLogger
106
+ Logger instance for debug and info logging.
107
+ """
81
108
  logger.info(f"Current Doc buffer size: {len(buffer)}, Gonna flush {len(buffer)} msgs to DocDBs!")
82
109
  for dao in doc_daos:
83
110
  dao.insert_and_update_many_tasks(buffer, TaskObject.task_id_field())
@@ -93,9 +120,12 @@ class DocumentInserter:
93
120
  message["workflow_id"] = wf_id
94
121
 
95
122
  if "campaign_id" not in message:
96
- campaign_id = self._mq_dao._keyvalue_dao.get_key("current_campaign_id")
97
- if campaign_id:
98
- message["campaign_id"] = campaign_id
123
+ try:
124
+ campaign_id = self._mq_dao._keyvalue_dao.get_key("current_campaign_id")
125
+ if campaign_id:
126
+ message["campaign_id"] = campaign_id
127
+ except Exception as e:
128
+ self.logger.error(e)
99
129
 
100
130
  if "subtype" not in message and "group_id" in message:
101
131
  message["subtype"] = "iteration"
@@ -113,6 +143,23 @@ class DocumentInserter:
113
143
 
114
144
  if ENRICH_MESSAGES:
115
145
  TaskObject.enrich_task_dict(message)
146
+ if (
147
+ "telemetry_at_start" in message
148
+ and message["telemetry_at_start"]
149
+ and "telemetry_at_end" in message
150
+ and message["telemetry_at_end"]
151
+ ):
152
+ try:
153
+ telemetry_summary = summarize_telemetry(message)
154
+ message["telemetry_summary"] = telemetry_summary
155
+ # TODO: make this dynamic
156
+ tags = tag_critical_task(
157
+ generated=message.get("generated", {}), telemetry_summary=telemetry_summary, thresholds=None
158
+ )
159
+ if tags:
160
+ message["tags"] = tags
161
+ except Exception as e:
162
+ self.logger.error(e) # TODO: check if cpu, etc is in the fields in for the telemetry_summary
116
163
 
117
164
  if REMOVE_EMPTY_FIELDS:
118
165
  remove_empty_fields_from_dict(message)
@@ -139,36 +186,71 @@ class DocumentInserter:
139
186
  f"in DocInserter from the interceptor "
140
187
  f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
141
188
  )
142
- self.logger.info(
143
- f"Begin register_time_based_thread_end "
144
- f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
145
- )
146
- self._mq_dao.register_time_based_thread_end(interceptor_instance_id, exec_bundle_id)
147
- self.logger.info(
148
- f"Done register_time_based_thread_end "
149
- f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
150
- )
189
+ if self.check_safe_stops:
190
+ self.logger.info(
191
+ f"Begin register_time_based_thread_end "
192
+ f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
193
+ )
194
+ self._mq_dao.register_time_based_thread_end(interceptor_instance_id, exec_bundle_id)
195
+ self.logger.info(
196
+ f"Done register_time_based_thread_end "
197
+ f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
198
+ )
151
199
  return "continue"
152
200
  elif message["info"] == "stop_document_inserter":
153
- self.logger.info("Document Inserter is stopping...")
154
- return "stop"
155
-
156
- def start(self, threaded=True) -> "DocumentInserter":
157
- """Start it."""
158
- self._mq_dao.subscribe()
159
- if threaded:
160
- self._main_thread = Thread(target=self._start)
161
- self._main_thread.start()
162
- else:
163
- self._start()
201
+ exec_bundle_id = message.get("exec_bundle_id", None)
202
+ if self._bundle_exec_id == exec_bundle_id:
203
+ self.logger.info(f"Document Inserter for exec_id {exec_bundle_id} is stopping...")
204
+ return "stop"
205
+ else:
206
+ return "continue"
207
+
208
+ def start(self, target: Callable = None, args: Tuple = (), threaded: bool = True, daemon=True):
209
+ """
210
+ Start the DocumentInserter thread.
211
+
212
+ Parameters
213
+ ----------
214
+ target : Callable, optional
215
+ Target function to run. Defaults to `self.thread_target`.
216
+ args : tuple, optional
217
+ Arguments to pass to the target function. Defaults to empty tuple.
218
+ threaded : bool, optional
219
+ Whether to run the inserter in a separate thread. Defaults to True.
220
+ daemon : bool, optional
221
+ Whether the thread should be a daemon. Defaults to True.
222
+
223
+ Returns
224
+ -------
225
+ DocumentInserter
226
+ The current instance of the DocumentInserter.
227
+ """
228
+ if not self._should_start:
229
+ self.logger.info("Doc Inserter cannot start as all DocDBs are disabled.")
230
+ return self
231
+ super().start(target=self.thread_target, threaded=threaded, daemon=daemon)
164
232
  return self
165
233
 
166
- def _start(self):
167
- self._mq_dao.message_listener(self._message_handler)
234
+ def thread_target(self):
235
+ """Function to be used in the self.start method."""
236
+ super().default_thread_target()
168
237
  self.buffer.stop()
169
238
  self.logger.info("Ok, we broke the doc inserter message listen loop!")
170
239
 
171
- def _message_handler(self, msg_obj: dict):
240
+ def message_handler(self, msg_obj: Dict):
241
+ """
242
+ Overrides the message_handler method by determining message's type and dispatching to the appropriate handler.
243
+
244
+ Parameters
245
+ ----------
246
+ msg_obj : dict
247
+ The message object received from the message queue.
248
+
249
+ Returns
250
+ -------
251
+ bool
252
+ False if a stop control message is received, True otherwise.
253
+ """
172
254
  msg_type = msg_obj.get("type")
173
255
  if msg_type == "flowcept_control":
174
256
  r = self._handle_control_message(msg_obj)
@@ -197,7 +279,22 @@ class DocumentInserter:
197
279
  return True
198
280
 
199
281
  def stop(self, bundle_exec_id=None):
200
- """Stop document inserter."""
282
+ """
283
+ Stop the DocumentInserter safely, waiting for all time-based threads to end.
284
+
285
+ Parameters
286
+ ----------
287
+ bundle_exec_id : str, optional
288
+ The execution bundle ID to check for safe stopping. If None, will not use it as a filter.
289
+
290
+ Notes
291
+ -----
292
+ This method flushes remaining buffered data, stops internal threads,
293
+ closes database connections, and clears campaign state from the key-value store.
294
+ """
295
+ if not self._should_start:
296
+ self.logger.info("Doc Inserter has not been started, so it can't stop.")
297
+ return self
201
298
  if self.check_safe_stops:
202
299
  trial = 0
203
300
  while not self._mq_dao.all_time_based_threads_ended(bundle_exec_id):
@@ -216,12 +313,14 @@ class DocumentInserter:
216
313
  msg = f"DocInserter {id(self)} gave up waiting for signal. "
217
314
  self.logger.critical(msg + "Safe to stop now.")
218
315
  break
316
+ self._mq_dao.delete_current_campaign_id()
317
+
219
318
  self.logger.info("Sending message to stop document inserter.")
220
- self._mq_dao.send_document_inserter_stop()
319
+ self._mq_dao.send_document_inserter_stop(exec_bundle_id=self._bundle_exec_id)
221
320
  self.logger.info(f"Doc Inserter {id(self)} Sent message to stop itself.")
222
321
  self._main_thread.join()
223
322
  for dao in self._doc_daos:
224
323
  self.logger.info(f"Closing document_inserter {dao.__class__.__name__} connection.")
225
324
  dao.close()
226
- self._mq_dao.delete_current_campaign_id()
325
+
227
326
  self.logger.info("Document Inserter is stopped.")
@@ -215,7 +215,7 @@ class TelemetryCapture:
215
215
 
216
216
  def capture(self) -> Telemetry:
217
217
  """Capture it."""
218
- if self.conf is None:
218
+ if not self.conf:
219
219
  return None
220
220
  tel = Telemetry()
221
221
  if self.conf.get("process_info", False):
@@ -59,6 +59,7 @@ class FlowceptTask(object):
59
59
  campaign_id: str = None,
60
60
  activity_id: str = None,
61
61
  used: Dict = None,
62
+ subtype: str = None,
62
63
  custom_metadata: Dict = None,
63
64
  ):
64
65
  if not INSTRUMENTATION_ENABLED:
@@ -66,13 +67,16 @@ class FlowceptTask(object):
66
67
  return
67
68
  self._task = TaskObject()
68
69
  self._interceptor = InstrumentationInterceptor.get_instance()
69
- self._task.telemetry_at_start = self._interceptor.telemetry_capture.capture()
70
+ tel = self._interceptor.telemetry_capture.capture()
71
+ if tel:
72
+ self._task.telemetry_at_start = tel
70
73
  self._task.activity_id = activity_id
71
74
  self._task.started_at = time()
72
75
  self._task.task_id = task_id or self._gen_task_id()
73
76
  self._task.workflow_id = workflow_id or Flowcept.current_workflow_id
74
77
  self._task.campaign_id = campaign_id or Flowcept.campaign_id
75
78
  self._task.used = used
79
+ self._task.subtype = subtype
76
80
  self._task.custom_metadata = custom_metadata
77
81
  self._ended = False
78
82
 
@@ -124,7 +128,9 @@ class FlowceptTask(object):
124
128
  """
125
129
  if not INSTRUMENTATION_ENABLED:
126
130
  return
127
- self._task.telemetry_at_end = self._interceptor.telemetry_capture.capture()
131
+ tel = self._interceptor.telemetry_capture.capture()
132
+ if tel:
133
+ self._task.telemetry_at_end = tel
128
134
  self._task.ended_at = ended_at or time()
129
135
  self._task.status = status
130
136
  self._task.stderr = stderr
flowcept/version.py CHANGED
@@ -4,4 +4,4 @@
4
4
  # The expected format is: <Major>.<Minor>.<Patch>
5
5
  # This file is supposed to be automatically modified by the CI Bot.
6
6
  # See .github/workflows/version_bumper.py
7
- __version__ = "0.8.10"
7
+ __version__ = "0.8.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowcept
3
- Version: 0.8.10
3
+ Version: 0.8.11
4
4
  Summary: Capture and query workflow provenance data using data observability
5
5
  Project-URL: GitHub, https://github.com/ORNL/flowcept
6
6
  Author: Oak Ridge National Laboratory
@@ -29,6 +29,7 @@ Requires-Dist: furo; extra == 'all'
29
29
  Requires-Dist: jupyterlab; extra == 'all'
30
30
  Requires-Dist: mlflow-skinny; extra == 'all'
31
31
  Requires-Dist: nbmake; extra == 'all'
32
+ Requires-Dist: paho-mqtt; extra == 'all'
32
33
  Requires-Dist: pika; extra == 'all'
33
34
  Requires-Dist: plotly; extra == 'all'
34
35
  Requires-Dist: pymongo; extra == 'all'
@@ -65,6 +66,12 @@ Requires-Dist: furo; extra == 'docs'
65
66
  Requires-Dist: sphinx; extra == 'docs'
66
67
  Provides-Extra: kafka
67
68
  Requires-Dist: confluent-kafka<=2.8.0; extra == 'kafka'
69
+ Provides-Extra: llm-agent
70
+ Requires-Dist: faiss-cpu; extra == 'llm-agent'
71
+ Requires-Dist: langchain-community; extra == 'llm-agent'
72
+ Requires-Dist: mcp[cli]; extra == 'llm-agent'
73
+ Requires-Dist: sentence-transformers; extra == 'llm-agent'
74
+ Requires-Dist: tiktoken; extra == 'llm-agent'
68
75
  Provides-Extra: ml-dev
69
76
  Requires-Dist: datasets==2.17.0; extra == 'ml-dev'
70
77
  Requires-Dist: nltk; extra == 'ml-dev'
@@ -80,6 +87,8 @@ Requires-Dist: sqlalchemy; extra == 'mlflow'
80
87
  Requires-Dist: watchdog; extra == 'mlflow'
81
88
  Provides-Extra: mongo
82
89
  Requires-Dist: pymongo; extra == 'mongo'
90
+ Provides-Extra: mqtt
91
+ Requires-Dist: paho-mqtt; extra == 'mqtt'
83
92
  Provides-Extra: nvidia
84
93
  Requires-Dist: nvidia-ml-py; extra == 'nvidia'
85
94
  Provides-Extra: tensorboard
@@ -1,7 +1,7 @@
1
1
  flowcept/__init__.py,sha256=CukmdzTUvm6Y_plTKPq4kKn7w9LdR36j7V_C_UQyjhU,2011
2
- flowcept/cli.py,sha256=WXslw2Utrn29DmJOHliptjNGpZC239IdjQdQ1dmuGVI,8638
3
- flowcept/configs.py,sha256=p4VB5cLmAI4NKpxrZ92jNEI1ZRPrex8Ef0Dxy23ecDk,7276
4
- flowcept/version.py,sha256=_nToyachA8IpRDDoW02cQ8d923faUb4KptrClM0bRf8,307
2
+ flowcept/cli.py,sha256=5rFPMle_fyXNiOvAgfCh8eIqR_vZKoY3aXbeORU8bcY,15117
3
+ flowcept/configs.py,sha256=PyZ0svU0DKLeSNMaLq8G62zsOrSL2RO1mPZorjTQs_Q,7458
4
+ flowcept/version.py,sha256=kZzuCD8eKygfSNYWrKZruE9fLy68IKgtP2XirWNoQso,307
5
5
  flowcept/analytics/__init__.py,sha256=46q-7vsHq_ddPNrzNnDgEOiRgvlx-5Ggu2ocyROMV0w,641
6
6
  flowcept/analytics/analytics_utils.py,sha256=FRJdBtQa7Hrk2oR_FFhmhmMf3X6YyZ4nbH5RIYh7KL4,8753
7
7
  flowcept/analytics/data_augmentation.py,sha256=Dyr5x316Zf-k1e8rVoQMCpFOrklYVHjfejRPrtoycmc,1641
@@ -10,28 +10,30 @@ flowcept/commons/__init__.py,sha256=W94CqapS0IGuuIGHHaz4sNuuiYhgtJWtpDEbnI0pGwI,
10
10
  flowcept/commons/autoflush_buffer.py,sha256=8M0fcIeHck-mSGQ2HFpW3_Af8-dHswhIbUMX5FATm48,2589
11
11
  flowcept/commons/flowcept_logger.py,sha256=0asRucrDMeRXvsdhuCmH6lWO7lAt_Z5o5uW7rrQhcjc,1857
12
12
  flowcept/commons/query_utils.py,sha256=3tyK5VYA10iDtmtzNwa8OQGn93DBxsu6rTjHDphftSc,2208
13
- flowcept/commons/settings_factory.py,sha256=vpvnpqabPKK-mzoZ5iLdnefpemW1MldDOZhii_m9wNk,1814
14
- flowcept/commons/utils.py,sha256=rT8ZbfVBXbnsDvINvRvcTRuz3tU0DJh79z9YM2Ydgrc,8416
13
+ flowcept/commons/settings_factory.py,sha256=bMTjgXRfb5HsL2lPnLfem-9trqELbNWE04Ie7lSlxYM,1731
14
+ flowcept/commons/task_data_preprocess.py,sha256=skTkT8XpO1gsIfu5YGHPj4A1qK4O139rELpwVmMryeY,6767
15
+ flowcept/commons/utils.py,sha256=nzNSAupZidI54ngNF67MX5H0gIj1YOq0GTv6A-z6eEE,8418
15
16
  flowcept/commons/vocabulary.py,sha256=_GzHJ1wSYJlLsu_uu1Am6N3zvc59S4FCuT5yp7lynPw,713
16
17
  flowcept/commons/daos/__init__.py,sha256=RO51svfHOg9naN676zuQwbj_RQ6IFHu-RALeefvtwwk,23
17
- flowcept/commons/daos/keyvalue_dao.py,sha256=03xHhQIfZas0LQLP1DbGJ5DoskXyZNXQKINhti0wH9A,3809
18
+ flowcept/commons/daos/keyvalue_dao.py,sha256=g7zgC9hVC1NTllwUAqGt44YqdqYUgAKgPlX8_G4BRGw,3599
19
+ flowcept/commons/daos/redis_conn.py,sha256=gFyW-5yf6B8ExEYopCmbap8ki-iEwuIw-KH9f6o7UGQ,1495
18
20
  flowcept/commons/daos/docdb_dao/__init__.py,sha256=qRvXREeUJ4mkhxdC9bzpOsVX6M2FB5hDyLFxhMxTGhs,30
19
21
  flowcept/commons/daos/docdb_dao/docdb_dao_base.py,sha256=YbfSVJPwZGK2GBYkeapRC83HkmP0c6Msv5TriD88RcI,11812
20
22
  flowcept/commons/daos/docdb_dao/lmdb_dao.py,sha256=dJOLgCx_lwdz6MKiMpM_UE4rm0angDCPaVz_WU5KqIA,10407
21
23
  flowcept/commons/daos/docdb_dao/mongodb_dao.py,sha256=0y9RiL54e1GxSTkRHFlMrLFAHWuB3YyNS2zLsnBPtxg,38456
22
24
  flowcept/commons/daos/mq_dao/__init__.py,sha256=Xxm4FmbBUZDQ7XIAmSFbeKE_AdHsbgFmSuftvMWSykQ,21
23
- flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=EAqOhy7Q8V29JFDG8C50nRK34KsPxEICkG4elk4ZfX8,9020
24
- flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=bf-bZvWw9JJk8Kdfzx2UkAnQC95rSrKXDEyYkrcncOk,4400
25
- flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=Q_mgZ3C_4gTTvnuJ2ZLmJgJfbAOopeSR9jvznI4JRuo,3948
26
- flowcept/commons/daos/mq_dao/mq_dao_redis.py,sha256=Br97SoDIkt4dHH937Yjg3wtkn1xGT-x9t-8E3VD5TeU,4277
25
+ flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=gXOHRhWHiJmN7mNRE4QIbnOfrN-314Ds2LONzsBw3Ug,9184
26
+ flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=Idq5TKm-dNZwlfkmLxUy7IBrn0DBtCekrC4n5dXUpn4,4379
27
+ flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=tRdMGYDzdeIJxad-B4-DE6u8Wzs61eTzOW4ojZrnTxs,4057
28
+ flowcept/commons/daos/mq_dao/mq_dao_redis.py,sha256=WKPoMPBSce4shqbBkgsnuqJAJoZZ4U_hdebhyFqtejQ,5535
27
29
  flowcept/commons/flowcept_dataclasses/__init__.py,sha256=8KkiJh0WSRAB50waVluxCSI8Tb9X1L9nup4c8RN3ulc,30
28
30
  flowcept/commons/flowcept_dataclasses/base_settings_dataclasses.py,sha256=Cjw2PGYtZDfnwecz6G3S42Ncmxj7AIZVEBx05bsxRUo,399
29
- flowcept/commons/flowcept_dataclasses/task_object.py,sha256=3DD5ZNMz7EVILS9PRkQ3khboav7lIKoUC5W6sKMFauQ,4694
31
+ flowcept/commons/flowcept_dataclasses/task_object.py,sha256=ZzUINqIm6s0J7M6a9OnzEcrBq5z8QZ-m_5n8UE0I6kI,5715
30
32
  flowcept/commons/flowcept_dataclasses/telemetry.py,sha256=9_5ONCo-06r5nKHXmi5HfIhiZSuPgmTECiq_u9MlxXM,2822
31
33
  flowcept/commons/flowcept_dataclasses/workflow_object.py,sha256=f8aB0b3xcUr3KQTlloF7R_P6xQejzDPOm-s6dLhGMeA,4383
32
34
  flowcept/flowcept_api/__init__.py,sha256=T1ty86YlocQ5Z18l5fUqHj_CC6Unq_iBv0lFyiI7Ao8,22
33
35
  flowcept/flowcept_api/db_api.py,sha256=hKXep-n50rp9cAzV0ljk2QVEF8O64yxi3ujXv5_Ibac,9723
34
- flowcept/flowcept_api/flowcept_controller.py,sha256=lkHR7O0zAAfbGtVa4o9tjZMdZquYN7vdnymRKzc4B8s,11933
36
+ flowcept/flowcept_api/flowcept_controller.py,sha256=_aB7x7ANOthpqD-xCA8UgiyeyabbzLpXgtpzkKXBBbw,12530
35
37
  flowcept/flowcept_api/task_query_api.py,sha256=SrwB0OCVtbpvCPECkE2ySM10G_g8Wlk5PJ8h-0xEaNc,23821
36
38
  flowcept/flowcept_webserver/__init__.py,sha256=8411GIXGddKTKoHUvbo_Rq6svosNG7tG8VzvUEBd7WI,28
37
39
  flowcept/flowcept_webserver/app.py,sha256=VUV8_JZbIbx9u_1O7m7XtRdhZb_7uifUa-iNlPhmZws,658
@@ -39,11 +41,18 @@ flowcept/flowcept_webserver/resources/__init__.py,sha256=XOk5yhLeLU6JmVXxbl3TY2z
39
41
  flowcept/flowcept_webserver/resources/query_rsrc.py,sha256=Mk1XDC_wVYkMk0eaazqWWrTC07gQU9U0toKfip0ihZE,1353
40
42
  flowcept/flowcept_webserver/resources/task_messages_rsrc.py,sha256=0u68it2W-9NzUUx5fWOZCqvRKe5EsLI8oyvto9634Ng,666
41
43
  flowcept/flowceptor/__init__.py,sha256=wVxRXUv07iNx6SMRRma2vqhR_GIcRl0re_WCYG65PUs,29
42
- flowcept/flowceptor/telemetry_capture.py,sha256=wSXyQJ-vPVzeldD4KqoLQA2rg7V0EOQo_11ErJE5oQQ,13743
44
+ flowcept/flowceptor/telemetry_capture.py,sha256=kDlRA1chkR31ckNuuQu7PmJPAO_yxwJ1-KRHJKW8csA,13739
43
45
  flowcept/flowceptor/adapters/__init__.py,sha256=SuZbSZVVQeBJ9zXW-M9jF09dw3XIjre3lSGrUO1Y8Po,27
44
- flowcept/flowceptor/adapters/base_interceptor.py,sha256=99a_Ipnj6g8qZMHWLBEYJh0Cox033ADxOKPFrivr9gw,6056
46
+ flowcept/flowceptor/adapters/base_interceptor.py,sha256=m2k_775gsiG7uEYEKLgA0KC4fysGTafbINCC4jkqd3M,6388
45
47
  flowcept/flowceptor/adapters/instrumentation_interceptor.py,sha256=DhK2bBnpghqPSeA62BUqRg6pl8zxuYrP33dK4x6PhRE,733
46
48
  flowcept/flowceptor/adapters/interceptor_state_manager.py,sha256=xRzmi5YFKBEqNtX8F5s6XlMTRe27ml4BmQtBO4WtG2c,919
49
+ flowcept/flowceptor/adapters/agents/__init__.py,sha256=5x_qyGaazppgvNDWbNhC_gfTav0b3r_P4CX7QwFv4BQ,32
50
+ flowcept/flowceptor/adapters/agents/agents_utils.py,sha256=JDxxsgcCdRR3CV3odIuLcHQcq-VFuApZaioqs_yHkuU,2798
51
+ flowcept/flowceptor/adapters/agents/flowcept_agent.py,sha256=13CobrSp_uObvLSVW3QNQOcqVa5rvwKBwFa4mjuLvb8,8173
52
+ flowcept/flowceptor/adapters/agents/flowcept_llm_prov_capture.py,sha256=2qzcItS3FHF-Wym_u9jZ-XzgDJnDgm9rGGRhfaqJZ8M,5992
53
+ flowcept/flowceptor/adapters/agents/prompts.py,sha256=VipBULibXYRF_mMCf_yYJ2Sb-aRNY_y7YTDmed4AfgM,2587
54
+ flowcept/flowceptor/adapters/brokers/__init__.py,sha256=mhQXVmh0JklvL93GUtJZLJnPRYX9Nmb8IqcyKJGQBzk,36
55
+ flowcept/flowceptor/adapters/brokers/mqtt_interceptor.py,sha256=wx3STMYPHeXB6ilUn-UQYsxesGp2hF7TRlfn52hNJtY,4845
47
56
  flowcept/flowceptor/adapters/dask/__init__.py,sha256=GKreb5L_nliD2BEckyB943zOQ-b6Gn1fLDj81FqSK2Y,23
48
57
  flowcept/flowceptor/adapters/dask/dask_dataclasses.py,sha256=6LTG-kdcc6AUuVINvkqB5QHw6pchg1aMqj0sdWt2Ef8,580
49
58
  flowcept/flowceptor/adapters/dask/dask_interceptor.py,sha256=uBQpLluYXzlT1gBDfTe4_WueC_fWBEs5Xr8ntpOmljE,5869
@@ -52,24 +61,27 @@ flowcept/flowceptor/adapters/mlflow/__init__.py,sha256=3mzHrvh1XQOy68qx1A3so9Nq2
52
61
  flowcept/flowceptor/adapters/mlflow/interception_event_handler.py,sha256=-SsIRdOcZjQUTzWgsZ41ouqpla4Qd32jIWXIAGU1pPw,494
53
62
  flowcept/flowceptor/adapters/mlflow/mlflow_dao.py,sha256=dPEgCduiw14_pzT5WCjuokwaN7p5Tu7UvWS2rtGh4qk,4589
54
63
  flowcept/flowceptor/adapters/mlflow/mlflow_dataclasses.py,sha256=vbijpDW6npHdsA9-28otXw94O4a9R-PWtq3xlJapsyY,690
55
- flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py,sha256=EjjcUx9xK7gx2rGJ83NfnK6noGWsfrOir_qH-aDreGY,3734
64
+ flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py,sha256=OLmVBdOCMS3GPcdxSdCD794RDbW6p4f8eBh1PXWcvHE,3799
56
65
  flowcept/flowceptor/adapters/tensorboard/__init__.py,sha256=LrcR4WCIlBwwHIUSteQ8k8JBdCJTFqLvvgAfnoLeREw,30
57
66
  flowcept/flowceptor/adapters/tensorboard/tensorboard_dataclasses.py,sha256=lSfDd6TucVNzGxbm69BYyCVgMr2p9iUEQjnsS4jIfeI,554
58
- flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py,sha256=VJmfnmtfvQ0ORYd21kMCb8D3XJgtV4Gf2sY_AIMCFzM,4803
59
- flowcept/flowceptor/adapters/zambeze/__init__.py,sha256=1e9_hK2cUKDXhQ0kBRftwcJjGFqbMVGisNP9oAuWpzk,26
60
- flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py,sha256=nn9MxvcdzgmOa8n5Jwdl7UzlSzxEu9bA-Ls6cHyb91c,849
61
- flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py,sha256=Bjyi48JW0DXJLJuvwPxaD8zxxsSoEFgSoXl8YcbwFWk,3782
67
+ flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py,sha256=PUKGlCsYcybsk1HK573Brs6FiXQRoaj6MKgZ3Oyeec4,4881
62
68
  flowcept/flowceptor/consumers/__init__.py,sha256=foxtVEb2ZEe9g1slfYIKM4tIFv-He1l7XS--SYs7nlQ,28
69
+ flowcept/flowceptor/consumers/base_consumer.py,sha256=xvs_BMrNFJhNX3ACEkf0DUH7JIJNtjNgg2xMRmujoiE,2935
63
70
  flowcept/flowceptor/consumers/consumer_utils.py,sha256=7bvFJWusJkfA4j0gwZLDIIsIOyfk9wRq6s5liS3JAV0,5665
64
- flowcept/flowceptor/consumers/document_inserter.py,sha256=dVUQPcWmvo68HhxJGlwUF9HtDLvofwwSTiNRwIe38PA,9164
71
+ flowcept/flowceptor/consumers/document_inserter.py,sha256=p5g18ghOrSbrR1b3btnBwZi48qMIvMT9n3QuRBq89LQ,13374
72
+ flowcept/flowceptor/consumers/agent/__init__.py,sha256=R1uvjBPeTLw9SpYgyUc6Qmo16pE84PFHcELTTFvyTWU,56
73
+ flowcept/flowceptor/consumers/agent/base_agent_context_manager.py,sha256=dRgWFuCacB_7lj1NfEeZM2uERmRTxh9QOxx1ywXtzfY,3226
74
+ flowcept/flowceptor/consumers/agent/client_agent.py,sha256=5dtjTRMHACIDwU_0k2xsKia24iasMM_6IMxWYCt5Ql8,1639
75
+ flowcept/flowceptor/consumers/agent/flowcept_agent_context_manager.py,sha256=RSdQ2zFkCizD2CtgdCIRRgs9J2E_G-49wmjNEZYoPMc,5302
76
+ flowcept/flowceptor/consumers/agent/flowcept_qa_manager.py,sha256=FaUTTixKncWjs-6xPw9BdNdPBFopFQ9tNRNT9kLPtyc,4156
65
77
  flowcept/instrumentation/__init__.py,sha256=M5bTmg80E4QyN91gUX3qfw_nbtJSXwGWcKxdZP3vJz0,34
66
78
  flowcept/instrumentation/flowcept_loop.py,sha256=RvETm3Pn37dIw_a1RXigyh2U7MCBHqi46dPmbrz3RMQ,12171
67
79
  flowcept/instrumentation/flowcept_task.py,sha256=l_BAYEUZ_SeBt8QJN_E9D9QcZVYRnW9qO_XRnqvmePE,5993
68
80
  flowcept/instrumentation/flowcept_torch.py,sha256=mH4sI2FMtBpGk4hN3U6MUwqd6sOPER8TbigUkexfhDY,23437
69
- flowcept/instrumentation/task_capture.py,sha256=bYL6ZricaGpkEu0vHIIldF0GERyZRCI31PpkuQH5jbc,4948
70
- resources/sample_settings.yaml,sha256=luy3EDwgNMTgJIfMrz08ahRK52vXmazvbA-wF_Lgt7U,5812
71
- flowcept-0.8.10.dist-info/METADATA,sha256=yxqHJsth888tg7cETFUogsas2QDjZjc3KBWrAL9julk,18426
72
- flowcept-0.8.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
73
- flowcept-0.8.10.dist-info/entry_points.txt,sha256=i8q67WE0201rVxYI2lyBtS52shvgl93x2Szp4q8zMlw,47
74
- flowcept-0.8.10.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
75
- flowcept-0.8.10.dist-info/RECORD,,
81
+ flowcept/instrumentation/task_capture.py,sha256=I3So1eysuyJ4KS3Fya14WldbgG0pBJ1CTvTikVKSEsM,5090
82
+ resources/sample_settings.yaml,sha256=cdMyRirOorBBVidUS2RVLs8NKlBjbN-SJZ2XDnloc3A,6313
83
+ flowcept-0.8.11.dist-info/METADATA,sha256=xZpXRV3xItrqcWvCFipJljywnlW8BGSMOC0d02q5qao,18811
84
+ flowcept-0.8.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
85
+ flowcept-0.8.11.dist-info/entry_points.txt,sha256=i8q67WE0201rVxYI2lyBtS52shvgl93x2Szp4q8zMlw,47
86
+ flowcept-0.8.11.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
87
+ flowcept-0.8.11.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
- flowcept_version: 0.8.10 # Version of the Flowcept package. This setting file is compatible with this version.
1
+ flowcept_version: 0.8.11 # Version of the Flowcept package. This setting file is compatible with this version.
2
2
 
3
3
  project:
4
4
  debug: true # Toggle debug mode. This will add a property `debug: true` to all saved data, making it easier to retrieve/delete them later.
@@ -39,18 +39,22 @@ experiment:
39
39
  mq:
40
40
  type: redis # or kafka or mofka; Please adjust the port (kafka's default is 9092; redis is 6379). If mofka, adjust the group_file.
41
41
  host: localhost
42
- # instances: ["localhost:6379"] # We can have multiple redis instances being accessed by the consumers but each interceptor will currently access one single redis.
42
+ # uri: ?
43
+ # instances: ["localhost:6379"] # We can have multiple MQ instances being accessed by the consumers but each interceptor will currently access one single MQ..
43
44
  port: 6379
44
45
  # group_file: mofka.json
45
46
  channel: interception
46
47
  buffer_size: 50
47
48
  insertion_buffer_time_secs: 5
48
49
  timing: false
50
+ # uri: use Redis connection uri here
49
51
  chunk_size: -1 # use 0 or -1 to disable this. Or simply omit this from the config file.
52
+ same_as_kvdb: false # Set this to true if you are using the same Redis instance both as an MQ and as the KV_DB. In that case, no need to repeat connection parameters in MQ. Use only what you define in KV_DB.
50
53
 
51
- kv_db: # You can optionally use KV == MQ if MQ is Redis. Otherwise, these will be the Redis instance credentials.
54
+ kv_db:
52
55
  host: localhost
53
56
  port: 6379
57
+ enabled: true
54
58
  # uri: use Redis connection uri here
55
59
 
56
60
  web_server:
@@ -75,6 +79,15 @@ db_buffer:
75
79
  stop_max_trials: 240 # Maximum number of trials before giving up when waiting for a fully safe stop (i.e., all records have been inserted as expected).
76
80
  stop_trials_sleep: 0.01 # Sleep duration (in seconds) between trials when waiting for a fully safe stop.
77
81
 
82
+ agent:
83
+ enabled: false
84
+ mcp_host: localhost
85
+ mcp_port: 8000
86
+ llm_server_url: '?'
87
+ api_key: '?'
88
+ model: '?'
89
+ model_kwargs: {}
90
+
78
91
  databases:
79
92
 
80
93
  lmdb:
@@ -90,16 +103,26 @@ databases:
90
103
 
91
104
  adapters:
92
105
  # For each key below, you can have multiple instances. Like mlflow1, mlflow2; zambeze1, zambeze2. Use an empty dict, {}, if you won't use any adapter.
93
- zambeze:
94
- kind: zambeze
95
- host: localhost
96
- port: 5672
97
- queue_names:
98
- - hello
99
- - hello2
100
- # key_values_to_filter:
101
- # - key: activity_status
102
- # value: CREATED
106
+
107
+ broker_mqtt:
108
+ kind: broker
109
+ host: h
110
+ port: 30011
111
+ protocol: mqtt3.1.1
112
+ queues: ["#"]
113
+ username: postman
114
+ password: p
115
+ qos: 2
116
+ task_subtype: intersect_msg
117
+ tracked_keys:
118
+ used: payload
119
+ generated: ~
120
+ custom_metadata: [headers, msgId]
121
+ activity_id: operationId
122
+ submitted_at: ~
123
+ started_at: ~
124
+ ended_at: ~
125
+ registered_at: ~
103
126
 
104
127
  mlflow:
105
128
  kind: mlflow
@@ -122,3 +145,4 @@ adapters:
122
145
  worker_should_get_output: true
123
146
  scheduler_create_timestamps: true
124
147
  worker_create_timestamps: false
148
+
@@ -1 +0,0 @@
1
- """Zambeze subpackage."""
@@ -1,41 +0,0 @@
1
- """Zambeze dataclass module."""
2
-
3
- from dataclasses import dataclass
4
- from typing import List, Dict
5
-
6
- from flowcept.commons.flowcept_dataclasses.base_settings_dataclasses import (
7
- BaseSettings,
8
- KeyValue,
9
- )
10
-
11
-
12
- @dataclass
13
- class ZambezeMessage:
14
- """Zambeze message."""
15
-
16
- name: str
17
- activity_id: str
18
- campaign_id: str
19
- origin_agent_id: str
20
- files: List[str]
21
- command: str
22
- activity_status: str
23
- arguments: List[str]
24
- kwargs: Dict
25
- depends_on: List[str]
26
-
27
-
28
- @dataclass
29
- class ZambezeSettings(BaseSettings):
30
- """Zambeze settings."""
31
-
32
- host: str
33
- port: int
34
- queue_names: List[str]
35
- key_values_to_filter: List[KeyValue] = None
36
- kind = "zambeze"
37
-
38
- def __post_init__(self):
39
- """Set attributes after init."""
40
- self.observer_type = "message_broker"
41
- self.observer_subtype = "rabbit_mq"