flowcept 0.8.9__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 +460 -0
  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 +11 -9
  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 +17 -19
  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 +138 -53
  31. flowcept/flowceptor/telemetry_capture.py +1 -1
  32. flowcept/instrumentation/task_capture.py +19 -9
  33. flowcept/version.py +1 -1
  34. {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/METADATA +18 -6
  35. {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/RECORD +39 -25
  36. flowcept-0.8.11.dist-info/entry_points.txt +2 -0
  37. resources/sample_settings.yaml +44 -23
  38. flowcept/flowceptor/adapters/zambeze/__init__.py +0 -1
  39. flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py +0 -41
  40. flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py +0 -102
  41. {flowcept-0.8.9.dist-info → flowcept-0.8.11.dist-info}/WHEEL +0 -0
  42. {flowcept-0.8.9.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,
@@ -16,11 +17,9 @@ from flowcept.commons.utils import GenericJSONDecoder
16
17
  from flowcept.commons.vocabulary import Status
17
18
  from flowcept.configs import (
18
19
  INSERTION_BUFFER_TIME,
19
- DB_MAX_BUFFER_SIZE,
20
- DB_MIN_BUFFER_SIZE,
20
+ DB_BUFFER_SIZE,
21
21
  DB_INSERTER_MAX_TRIALS_STOP,
22
22
  DB_INSERTER_SLEEP_TRIALS_STOP,
23
- ADAPTIVE_DB_BUFFER_SIZE,
24
23
  REMOVE_EMPTY_FIELDS,
25
24
  JSON_SERIALIZER,
26
25
  ENRICH_MESSAGES,
@@ -32,8 +31,18 @@ from flowcept.flowceptor.consumers.consumer_utils import (
32
31
  )
33
32
 
34
33
 
35
- class DocumentInserter:
36
- """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
+ """
37
46
 
38
47
  DECODER = GenericJSONDecoder if JSON_SERIALIZER == "complex" else None
39
48
 
@@ -54,8 +63,8 @@ class DocumentInserter:
54
63
  check_safe_stops=True,
55
64
  bundle_exec_id=None,
56
65
  ):
57
- self._mq_dao = MQDao.build()
58
66
  self._doc_daos = []
67
+ self.logger = FlowceptLogger()
59
68
  if MONGO_ENABLED:
60
69
  from flowcept.commons.daos.docdb_dao.mongodb_dao import MongoDBDAO
61
70
 
@@ -64,34 +73,38 @@ class DocumentInserter:
64
73
  from flowcept.commons.daos.docdb_dao.lmdb_dao import LMDBDAO
65
74
 
66
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__()
67
82
  self._previous_time = time()
68
- self.logger = FlowceptLogger()
69
83
  self._main_thread: Thread = None
70
- self._curr_max_buffer_size = DB_MAX_BUFFER_SIZE
84
+ self._curr_db_buffer_size = DB_BUFFER_SIZE
71
85
  self._bundle_exec_id = bundle_exec_id
72
86
  self.check_safe_stops = check_safe_stops
73
87
  self.buffer: AutoflushBuffer = AutoflushBuffer(
74
88
  flush_function=DocumentInserter.flush_function,
75
89
  flush_function_kwargs={"logger": self.logger, "doc_daos": self._doc_daos},
76
- max_size=self._curr_max_buffer_size,
90
+ max_size=self._curr_db_buffer_size,
77
91
  flush_interval=INSERTION_BUFFER_TIME,
78
92
  )
79
93
 
80
- def _set_buffer_size(self):
81
- if not ADAPTIVE_DB_BUFFER_SIZE:
82
- return
83
- else:
84
- self._curr_max_buffer_size = max(
85
- DB_MIN_BUFFER_SIZE,
86
- min(
87
- DB_MAX_BUFFER_SIZE,
88
- int(self._curr_max_buffer_size * 1.1),
89
- ),
90
- )
91
-
92
94
  @staticmethod
93
95
  def flush_function(buffer, doc_daos, logger):
94
- """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
+ """
95
108
  logger.info(f"Current Doc buffer size: {len(buffer)}, Gonna flush {len(buffer)} msgs to DocDBs!")
96
109
  for dao in doc_daos:
97
110
  dao.insert_and_update_many_tasks(buffer, TaskObject.task_id_field())
@@ -107,9 +120,12 @@ class DocumentInserter:
107
120
  message["workflow_id"] = wf_id
108
121
 
109
122
  if "campaign_id" not in message:
110
- campaign_id = self._mq_dao._keyvalue_dao.get_key("current_campaign_id")
111
- if campaign_id:
112
- 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)
113
129
 
114
130
  if "subtype" not in message and "group_id" in message:
115
131
  message["subtype"] = "iteration"
@@ -127,6 +143,23 @@ class DocumentInserter:
127
143
 
128
144
  if ENRICH_MESSAGES:
129
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
130
163
 
131
164
  if REMOVE_EMPTY_FIELDS:
132
165
  remove_empty_fields_from_dict(message)
@@ -153,36 +186,71 @@ class DocumentInserter:
153
186
  f"in DocInserter from the interceptor "
154
187
  f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
155
188
  )
156
- self.logger.info(
157
- f"Begin register_time_based_thread_end "
158
- f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
159
- )
160
- self._mq_dao.register_time_based_thread_end(interceptor_instance_id, exec_bundle_id)
161
- self.logger.info(
162
- f"Done register_time_based_thread_end "
163
- f"{'' if exec_bundle_id is None else exec_bundle_id}_{interceptor_instance_id}!"
164
- )
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
+ )
165
199
  return "continue"
166
200
  elif message["info"] == "stop_document_inserter":
167
- self.logger.info("Document Inserter is stopping...")
168
- return "stop"
169
-
170
- def start(self, threaded=True) -> "DocumentInserter":
171
- """Start it."""
172
- self._mq_dao.subscribe()
173
- if threaded:
174
- self._main_thread = Thread(target=self._start)
175
- self._main_thread.start()
176
- else:
177
- 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)
178
232
  return self
179
233
 
180
- def _start(self):
181
- 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()
182
237
  self.buffer.stop()
183
238
  self.logger.info("Ok, we broke the doc inserter message listen loop!")
184
239
 
185
- 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
+ """
186
254
  msg_type = msg_obj.get("type")
187
255
  if msg_type == "flowcept_control":
188
256
  r = self._handle_control_message(msg_obj)
@@ -211,7 +279,22 @@ class DocumentInserter:
211
279
  return True
212
280
 
213
281
  def stop(self, bundle_exec_id=None):
214
- """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
215
298
  if self.check_safe_stops:
216
299
  trial = 0
217
300
  while not self._mq_dao.all_time_based_threads_ended(bundle_exec_id):
@@ -230,12 +313,14 @@ class DocumentInserter:
230
313
  msg = f"DocInserter {id(self)} gave up waiting for signal. "
231
314
  self.logger.critical(msg + "Safe to stop now.")
232
315
  break
316
+ self._mq_dao.delete_current_campaign_id()
317
+
233
318
  self.logger.info("Sending message to stop document inserter.")
234
- self._mq_dao.send_document_inserter_stop()
319
+ self._mq_dao.send_document_inserter_stop(exec_bundle_id=self._bundle_exec_id)
235
320
  self.logger.info(f"Doc Inserter {id(self)} Sent message to stop itself.")
236
321
  self._main_thread.join()
237
322
  for dao in self._doc_daos:
238
323
  self.logger.info(f"Closing document_inserter {dao.__class__.__name__} connection.")
239
324
  dao.close()
240
- self._mq_dao.delete_current_campaign_id()
325
+
241
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):
@@ -1,5 +1,8 @@
1
1
  from time import time
2
2
  from typing import Dict
3
+ import os
4
+ import threading
5
+ import random
3
6
 
4
7
  from flowcept.commons.flowcept_dataclasses.task_object import (
5
8
  TaskObject,
@@ -56,25 +59,24 @@ class FlowceptTask(object):
56
59
  campaign_id: str = None,
57
60
  activity_id: str = None,
58
61
  used: Dict = None,
62
+ subtype: str = None,
59
63
  custom_metadata: Dict = None,
60
- flowcept: "Flowcept" = None,
61
64
  ):
62
65
  if not INSTRUMENTATION_ENABLED:
63
66
  self._ended = True
64
67
  return
65
- if flowcept is not None and flowcept._interceptor_instances[0].kind == "instrumentation":
66
- self._interceptor = flowcept._interceptor_instances[0]
67
- else:
68
- self._interceptor = InstrumentationInterceptor.get_instance()
69
-
70
68
  self._task = TaskObject()
71
- self._task.telemetry_at_start = self._interceptor.telemetry_capture.capture()
69
+ self._interceptor = InstrumentationInterceptor.get_instance()
70
+ tel = self._interceptor.telemetry_capture.capture()
71
+ if tel:
72
+ self._task.telemetry_at_start = tel
72
73
  self._task.activity_id = activity_id
73
74
  self._task.started_at = time()
74
- self._task.task_id = task_id or str(self._task.started_at)
75
+ self._task.task_id = task_id or self._gen_task_id()
75
76
  self._task.workflow_id = workflow_id or Flowcept.current_workflow_id
76
77
  self._task.campaign_id = campaign_id or Flowcept.campaign_id
77
78
  self._task.used = used
79
+ self._task.subtype = subtype
78
80
  self._task.custom_metadata = custom_metadata
79
81
  self._ended = False
80
82
 
@@ -85,6 +87,12 @@ class FlowceptTask(object):
85
87
  if not self._ended:
86
88
  self.end()
87
89
 
90
+ def _gen_task_id(self):
91
+ pid = os.getpid()
92
+ tid = threading.get_ident()
93
+ rand = random.getrandbits(32)
94
+ return f"{self._task.started_at}_{pid}_{tid}_{rand}"
95
+
88
96
  def end(
89
97
  self,
90
98
  generated: Dict = None,
@@ -120,7 +128,9 @@ class FlowceptTask(object):
120
128
  """
121
129
  if not INSTRUMENTATION_ENABLED:
122
130
  return
123
- 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
124
134
  self._task.ended_at = ended_at or time()
125
135
  self._task.status = status
126
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.9"
7
+ __version__ = "0.8.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowcept
3
- Version: 0.8.9
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
@@ -112,7 +121,9 @@ Description-Content-Type: text/markdown
112
121
 
113
122
  ## Overview
114
123
 
115
- Flowcept is a runtime data integration system that captures and queries workflow provenance with minimal or no code changes. It unifies data across diverse workflows and tools, enabling integrated analysis and insights, especially in federated environments. Designed for scenarios involving critical data from multiple workflows, Flowcept seamlessly integrates data at runtime, providing a unified view for end-to-end monitoring and analysis, and enhanced support for Machine Learning (ML) workflows.
124
+ Flowcept is a runtime data integration system that captures and queries workflow provenance with minimal or no code changes. It unifies data from diverse workflows and tools, enabling integrated analysis and insights, especially in federated environments.
125
+
126
+ Designed for scenarios involving critical data from multiple workflows, Flowcept supports end-to-end monitoring, analysis, querying, and enhanced support for Machine Learning (ML) workflows.
116
127
 
117
128
  ## Features
118
129
 
@@ -135,8 +146,9 @@ Notes:
135
146
  - TensorBoard
136
147
  - Python scripts can be easily instrumented via `@decorators` using `@flowcept_task` (for generic Python method) or `@torch_task` (for methods that encapsulate PyTorch model manipulation, such as training or evaluation).
137
148
  - Currently supported MQ systems:
138
- - Kafka
139
- - Redis
149
+ - [Kafka](https://kafka.apache.org)
150
+ - [Redis](https://redis.io)
151
+ - [Mofka](https://mofka.readthedocs.io)
140
152
  - Currently supported database systems:
141
153
  - MongoDB
142
154
  - Lightning Memory-Mapped Database (lightweight file-only database system)
@@ -181,7 +193,7 @@ If you want to install all optional dependencies, use:
181
193
  pip install flowcept[all]
182
194
  ```
183
195
 
184
- This is a convenient way to ensure all adapters are available, but it may install dependencies you don't need.
196
+ This is useful mostly for Flowcept developers. Please avoid installing like this if you can, as it may install several dependencies you will never use.
185
197
 
186
198
  ### 4. Installing from Source
187
199
  To install Flowcept from the source repository:
@@ -363,7 +375,7 @@ Some unit tests utilize `torch==2.2.2`, `torchtext=0.17.2`, and `torchvision==0.
363
375
 
364
376
  ## Documentation
365
377
 
366
- Full documentation is available on [Read the Docs](https://myproject.readthedocs.io/en/latest/).
378
+ Full documentation is available on [Read the Docs](https://flowcept.readthedocs.io/).
367
379
 
368
380
  ## Cite us
369
381
 
@@ -1,6 +1,7 @@
1
1
  flowcept/__init__.py,sha256=CukmdzTUvm6Y_plTKPq4kKn7w9LdR36j7V_C_UQyjhU,2011
2
- flowcept/configs.py,sha256=NDUAqqoKfztt6Qjwxy95eTQU71AovVJWXalI1x3HJ7Y,7441
3
- flowcept/version.py,sha256=5K2nK5n8mOoa4RCuo6y59WqFAvyjbjOF54ItBa7TE_w,306
2
+ flowcept/cli.py,sha256=5rFPMle_fyXNiOvAgfCh8eIqR_vZKoY3aXbeORU8bcY,15117
3
+ flowcept/configs.py,sha256=PyZ0svU0DKLeSNMaLq8G62zsOrSL2RO1mPZorjTQs_Q,7458
4
+ flowcept/version.py,sha256=kZzuCD8eKygfSNYWrKZruE9fLy68IKgtP2XirWNoQso,307
4
5
  flowcept/analytics/__init__.py,sha256=46q-7vsHq_ddPNrzNnDgEOiRgvlx-5Ggu2ocyROMV0w,641
5
6
  flowcept/analytics/analytics_utils.py,sha256=FRJdBtQa7Hrk2oR_FFhmhmMf3X6YyZ4nbH5RIYh7KL4,8753
6
7
  flowcept/analytics/data_augmentation.py,sha256=Dyr5x316Zf-k1e8rVoQMCpFOrklYVHjfejRPrtoycmc,1641
@@ -9,28 +10,30 @@ flowcept/commons/__init__.py,sha256=W94CqapS0IGuuIGHHaz4sNuuiYhgtJWtpDEbnI0pGwI,
9
10
  flowcept/commons/autoflush_buffer.py,sha256=8M0fcIeHck-mSGQ2HFpW3_Af8-dHswhIbUMX5FATm48,2589
10
11
  flowcept/commons/flowcept_logger.py,sha256=0asRucrDMeRXvsdhuCmH6lWO7lAt_Z5o5uW7rrQhcjc,1857
11
12
  flowcept/commons/query_utils.py,sha256=3tyK5VYA10iDtmtzNwa8OQGn93DBxsu6rTjHDphftSc,2208
12
- flowcept/commons/settings_factory.py,sha256=vpvnpqabPKK-mzoZ5iLdnefpemW1MldDOZhii_m9wNk,1814
13
- 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
14
16
  flowcept/commons/vocabulary.py,sha256=_GzHJ1wSYJlLsu_uu1Am6N3zvc59S4FCuT5yp7lynPw,713
15
17
  flowcept/commons/daos/__init__.py,sha256=RO51svfHOg9naN676zuQwbj_RQ6IFHu-RALeefvtwwk,23
16
- 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
17
20
  flowcept/commons/daos/docdb_dao/__init__.py,sha256=qRvXREeUJ4mkhxdC9bzpOsVX6M2FB5hDyLFxhMxTGhs,30
18
21
  flowcept/commons/daos/docdb_dao/docdb_dao_base.py,sha256=YbfSVJPwZGK2GBYkeapRC83HkmP0c6Msv5TriD88RcI,11812
19
22
  flowcept/commons/daos/docdb_dao/lmdb_dao.py,sha256=dJOLgCx_lwdz6MKiMpM_UE4rm0angDCPaVz_WU5KqIA,10407
20
23
  flowcept/commons/daos/docdb_dao/mongodb_dao.py,sha256=0y9RiL54e1GxSTkRHFlMrLFAHWuB3YyNS2zLsnBPtxg,38456
21
24
  flowcept/commons/daos/mq_dao/__init__.py,sha256=Xxm4FmbBUZDQ7XIAmSFbeKE_AdHsbgFmSuftvMWSykQ,21
22
- flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=EAqOhy7Q8V29JFDG8C50nRK34KsPxEICkG4elk4ZfX8,9020
23
- flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=bf-bZvWw9JJk8Kdfzx2UkAnQC95rSrKXDEyYkrcncOk,4400
24
- flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=Q_mgZ3C_4gTTvnuJ2ZLmJgJfbAOopeSR9jvznI4JRuo,3948
25
- 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
26
29
  flowcept/commons/flowcept_dataclasses/__init__.py,sha256=8KkiJh0WSRAB50waVluxCSI8Tb9X1L9nup4c8RN3ulc,30
27
30
  flowcept/commons/flowcept_dataclasses/base_settings_dataclasses.py,sha256=Cjw2PGYtZDfnwecz6G3S42Ncmxj7AIZVEBx05bsxRUo,399
28
- flowcept/commons/flowcept_dataclasses/task_object.py,sha256=3DD5ZNMz7EVILS9PRkQ3khboav7lIKoUC5W6sKMFauQ,4694
31
+ flowcept/commons/flowcept_dataclasses/task_object.py,sha256=ZzUINqIm6s0J7M6a9OnzEcrBq5z8QZ-m_5n8UE0I6kI,5715
29
32
  flowcept/commons/flowcept_dataclasses/telemetry.py,sha256=9_5ONCo-06r5nKHXmi5HfIhiZSuPgmTECiq_u9MlxXM,2822
30
33
  flowcept/commons/flowcept_dataclasses/workflow_object.py,sha256=f8aB0b3xcUr3KQTlloF7R_P6xQejzDPOm-s6dLhGMeA,4383
31
34
  flowcept/flowcept_api/__init__.py,sha256=T1ty86YlocQ5Z18l5fUqHj_CC6Unq_iBv0lFyiI7Ao8,22
32
35
  flowcept/flowcept_api/db_api.py,sha256=hKXep-n50rp9cAzV0ljk2QVEF8O64yxi3ujXv5_Ibac,9723
33
- flowcept/flowcept_api/flowcept_controller.py,sha256=lkHR7O0zAAfbGtVa4o9tjZMdZquYN7vdnymRKzc4B8s,11933
36
+ flowcept/flowcept_api/flowcept_controller.py,sha256=_aB7x7ANOthpqD-xCA8UgiyeyabbzLpXgtpzkKXBBbw,12530
34
37
  flowcept/flowcept_api/task_query_api.py,sha256=SrwB0OCVtbpvCPECkE2ySM10G_g8Wlk5PJ8h-0xEaNc,23821
35
38
  flowcept/flowcept_webserver/__init__.py,sha256=8411GIXGddKTKoHUvbo_Rq6svosNG7tG8VzvUEBd7WI,28
36
39
  flowcept/flowcept_webserver/app.py,sha256=VUV8_JZbIbx9u_1O7m7XtRdhZb_7uifUa-iNlPhmZws,658
@@ -38,11 +41,18 @@ flowcept/flowcept_webserver/resources/__init__.py,sha256=XOk5yhLeLU6JmVXxbl3TY2z
38
41
  flowcept/flowcept_webserver/resources/query_rsrc.py,sha256=Mk1XDC_wVYkMk0eaazqWWrTC07gQU9U0toKfip0ihZE,1353
39
42
  flowcept/flowcept_webserver/resources/task_messages_rsrc.py,sha256=0u68it2W-9NzUUx5fWOZCqvRKe5EsLI8oyvto9634Ng,666
40
43
  flowcept/flowceptor/__init__.py,sha256=wVxRXUv07iNx6SMRRma2vqhR_GIcRl0re_WCYG65PUs,29
41
- flowcept/flowceptor/telemetry_capture.py,sha256=wSXyQJ-vPVzeldD4KqoLQA2rg7V0EOQo_11ErJE5oQQ,13743
44
+ flowcept/flowceptor/telemetry_capture.py,sha256=kDlRA1chkR31ckNuuQu7PmJPAO_yxwJ1-KRHJKW8csA,13739
42
45
  flowcept/flowceptor/adapters/__init__.py,sha256=SuZbSZVVQeBJ9zXW-M9jF09dw3XIjre3lSGrUO1Y8Po,27
43
- flowcept/flowceptor/adapters/base_interceptor.py,sha256=a2CX7COCpYzIpQeVulrLJTSVIw453U-S2gmrMlouO5A,6487
46
+ flowcept/flowceptor/adapters/base_interceptor.py,sha256=m2k_775gsiG7uEYEKLgA0KC4fysGTafbINCC4jkqd3M,6388
44
47
  flowcept/flowceptor/adapters/instrumentation_interceptor.py,sha256=DhK2bBnpghqPSeA62BUqRg6pl8zxuYrP33dK4x6PhRE,733
45
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
46
56
  flowcept/flowceptor/adapters/dask/__init__.py,sha256=GKreb5L_nliD2BEckyB943zOQ-b6Gn1fLDj81FqSK2Y,23
47
57
  flowcept/flowceptor/adapters/dask/dask_dataclasses.py,sha256=6LTG-kdcc6AUuVINvkqB5QHw6pchg1aMqj0sdWt2Ef8,580
48
58
  flowcept/flowceptor/adapters/dask/dask_interceptor.py,sha256=uBQpLluYXzlT1gBDfTe4_WueC_fWBEs5Xr8ntpOmljE,5869
@@ -51,23 +61,27 @@ flowcept/flowceptor/adapters/mlflow/__init__.py,sha256=3mzHrvh1XQOy68qx1A3so9Nq2
51
61
  flowcept/flowceptor/adapters/mlflow/interception_event_handler.py,sha256=-SsIRdOcZjQUTzWgsZ41ouqpla4Qd32jIWXIAGU1pPw,494
52
62
  flowcept/flowceptor/adapters/mlflow/mlflow_dao.py,sha256=dPEgCduiw14_pzT5WCjuokwaN7p5Tu7UvWS2rtGh4qk,4589
53
63
  flowcept/flowceptor/adapters/mlflow/mlflow_dataclasses.py,sha256=vbijpDW6npHdsA9-28otXw94O4a9R-PWtq3xlJapsyY,690
54
- flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py,sha256=EjjcUx9xK7gx2rGJ83NfnK6noGWsfrOir_qH-aDreGY,3734
64
+ flowcept/flowceptor/adapters/mlflow/mlflow_interceptor.py,sha256=OLmVBdOCMS3GPcdxSdCD794RDbW6p4f8eBh1PXWcvHE,3799
55
65
  flowcept/flowceptor/adapters/tensorboard/__init__.py,sha256=LrcR4WCIlBwwHIUSteQ8k8JBdCJTFqLvvgAfnoLeREw,30
56
66
  flowcept/flowceptor/adapters/tensorboard/tensorboard_dataclasses.py,sha256=lSfDd6TucVNzGxbm69BYyCVgMr2p9iUEQjnsS4jIfeI,554
57
- flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py,sha256=VJmfnmtfvQ0ORYd21kMCb8D3XJgtV4Gf2sY_AIMCFzM,4803
58
- flowcept/flowceptor/adapters/zambeze/__init__.py,sha256=1e9_hK2cUKDXhQ0kBRftwcJjGFqbMVGisNP9oAuWpzk,26
59
- flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py,sha256=nn9MxvcdzgmOa8n5Jwdl7UzlSzxEu9bA-Ls6cHyb91c,849
60
- flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py,sha256=Bjyi48JW0DXJLJuvwPxaD8zxxsSoEFgSoXl8YcbwFWk,3782
67
+ flowcept/flowceptor/adapters/tensorboard/tensorboard_interceptor.py,sha256=PUKGlCsYcybsk1HK573Brs6FiXQRoaj6MKgZ3Oyeec4,4881
61
68
  flowcept/flowceptor/consumers/__init__.py,sha256=foxtVEb2ZEe9g1slfYIKM4tIFv-He1l7XS--SYs7nlQ,28
69
+ flowcept/flowceptor/consumers/base_consumer.py,sha256=xvs_BMrNFJhNX3ACEkf0DUH7JIJNtjNgg2xMRmujoiE,2935
62
70
  flowcept/flowceptor/consumers/consumer_utils.py,sha256=7bvFJWusJkfA4j0gwZLDIIsIOyfk9wRq6s5liS3JAV0,5665
63
- flowcept/flowceptor/consumers/document_inserter.py,sha256=fNPLa25oNhr3Y6-pRvzRp1zO4j3WBg7YXRnSHyDaaCo,9568
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
64
77
  flowcept/instrumentation/__init__.py,sha256=M5bTmg80E4QyN91gUX3qfw_nbtJSXwGWcKxdZP3vJz0,34
65
78
  flowcept/instrumentation/flowcept_loop.py,sha256=RvETm3Pn37dIw_a1RXigyh2U7MCBHqi46dPmbrz3RMQ,12171
66
79
  flowcept/instrumentation/flowcept_task.py,sha256=l_BAYEUZ_SeBt8QJN_E9D9QcZVYRnW9qO_XRnqvmePE,5993
67
80
  flowcept/instrumentation/flowcept_torch.py,sha256=mH4sI2FMtBpGk4hN3U6MUwqd6sOPER8TbigUkexfhDY,23437
68
- flowcept/instrumentation/task_capture.py,sha256=fbTAhf4y69pRCpnaH8r0dczSmPyNINSpljMrVyUnp0U,4945
69
- resources/sample_settings.yaml,sha256=GOF08TCRd80Vl6LoftCLQaE9XsjR_MmM56S2zTG0wEU,4957
70
- flowcept-0.8.9.dist-info/METADATA,sha256=v_bTyskKfNq36sibkc4mgx9woxk3IH6WfJOhspvIxVU,18357
71
- flowcept-0.8.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
72
- flowcept-0.8.9.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
73
- flowcept-0.8.9.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,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ flowcept = flowcept.cli:main