flowcept 0.9.2__py3-none-any.whl → 0.9.3__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.
@@ -53,7 +53,7 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
53
53
  Current application context holding task state and QA components.
54
54
  msgs_counter : int
55
55
  Counter tracking how many task messages have been processed.
56
- context_size : int
56
+ context_chunk_size : int
57
57
  Number of task messages to collect before triggering QA index building and LLM analysis.
58
58
  qa_manager : FlowceptQAManager
59
59
  Utility for constructing QA chains from task summaries.
@@ -64,7 +64,7 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
64
64
  self.tracker_config = dict(max_examples=3, max_str_len=50)
65
65
  self.schema_tracker = DynamicSchemaTracker(**self.tracker_config)
66
66
  self.msgs_counter = 0
67
- self.context_size = 1
67
+ self.context_chunk_size = 1 # Should be in the settings
68
68
  super().__init__()
69
69
 
70
70
  def message_handler(self, msg_obj: Dict):
@@ -98,18 +98,22 @@ class FlowceptAgentContextManager(BaseAgentContextManager):
98
98
  if len(task_summary.get("tags", [])):
99
99
  self.context.critical_tasks.append(task_summary)
100
100
 
101
- if self.msgs_counter > 0 and self.msgs_counter % self.context_size == 0:
101
+ if self.msgs_counter > 0 and self.msgs_counter % self.context_chunk_size == 0:
102
102
  self.logger.debug(
103
- f"Going to add to index! {(self.msgs_counter - self.context_size, self.msgs_counter)}"
103
+ f"Going to add to index! {(self.msgs_counter - self.context_chunk_size, self.msgs_counter)}"
104
104
  )
105
105
  try:
106
106
  self.update_schema_and_add_to_df(
107
- tasks=self.context.task_summaries[self.msgs_counter - self.context_size : self.msgs_counter]
107
+ tasks=self.context.task_summaries[
108
+ self.msgs_counter - self.context_chunk_size : self.msgs_counter
109
+ ]
108
110
  )
109
111
  except Exception as e:
110
112
  self.logger.error(
111
113
  f"Could not add these tasks to buffer!\n"
112
- f"{self.context.task_summaries[self.msgs_counter - self.context_size : self.msgs_counter]}"
114
+ f"{
115
+ self.context.task_summaries[self.msgs_counter - self.context_chunk_size : self.msgs_counter]
116
+ }"
113
117
  )
114
118
  self.logger.exception(e)
115
119
 
@@ -1,3 +1,5 @@
1
+ import base64
2
+ import ast
1
3
  import io
2
4
  import json
3
5
 
@@ -122,6 +124,53 @@ def display_ai_msg_from_tool(tool_result: ToolResult):
122
124
  return agent_reply
123
125
 
124
126
 
127
+ def _sniff_mime(b: bytes) -> str:
128
+ if b.startswith(b"\x89PNG\r\n\x1a\n"):
129
+ return "image/png"
130
+ if b.startswith(b"\xff\xd8\xff"):
131
+ return "image/jpeg"
132
+ if b.startswith(b"GIF87a") or b.startswith(b"GIF89a"):
133
+ return "image/gif"
134
+ if b.startswith(b"BM"):
135
+ return "image/bmp"
136
+ if b.startswith(b"RIFF") and b[8:12] == b"WEBP":
137
+ return "image/webp"
138
+ return "application/octet-stream"
139
+
140
+
141
+ def ensure_data_uri(val):
142
+ r"""Accepts bytes/bytearray/memoryview or a repr like \"b'\\x89PNG...'\" and returns a data URL."""
143
+ if isinstance(val, str) and val.startswith("data:"):
144
+ return val
145
+ if isinstance(val, str) and val.startswith("b'"):
146
+ try:
147
+ val = ast.literal_eval(val) # turn repr into bytes
148
+ except Exception:
149
+ return None
150
+ if isinstance(val, memoryview):
151
+ val = val.tobytes()
152
+ if isinstance(val, bytearray):
153
+ val = bytes(val)
154
+ if isinstance(val, bytes):
155
+ mime = _sniff_mime(val)
156
+ return f"data:{mime};base64,{base64.b64encode(val).decode('ascii')}"
157
+ return val # path/URL, etc.
158
+
159
+
160
+ def _render_df(df: pd.DataFrame, image_width: int = 90, row_height: int = 90):
161
+ if "image" in df.columns:
162
+ df = df.copy()
163
+ df["image"] = df["image"].apply(ensure_data_uri)
164
+ st.dataframe(
165
+ df,
166
+ column_config={"image": st.column_config.ImageColumn("Preview", width=image_width)},
167
+ hide_index=True,
168
+ row_height=row_height, # make thumbnails visible
169
+ )
170
+ else:
171
+ st.dataframe(df, hide_index=True)
172
+
173
+
125
174
  def display_df_tool_response(tool_result: ToolResult):
126
175
  r"""
127
176
  Display the DataFrame contained in a ToolResult.
@@ -170,7 +219,8 @@ def display_df_tool_response(tool_result: ToolResult):
170
219
  df = pd.read_csv(io.StringIO(result_df_str))
171
220
  print("The result is a df")
172
221
  if not df.empty:
173
- st.dataframe(df, hide_index=False)
222
+ _render_df(df)
223
+
174
224
  print("Columns", str(df.columns))
175
225
  print("Number of columns", len(df.columns))
176
226
  else:
@@ -190,6 +240,7 @@ def display_df_tool_response(tool_result: ToolResult):
190
240
 
191
241
  if summary:
192
242
  st.markdown("📝 Summary:")
243
+ print(f"THIS IS THE SUMMARY\n{summary}")
193
244
  st.markdown(summary)
194
245
  elif summary_error:
195
246
  st.markdown(f"⚠️ Encountered this error when summarizing the result dataframe:\n```text\n{summary_error}")
@@ -15,6 +15,7 @@ COMMON_TASK_FIELDS = """
15
15
  | `ended_at` | datetime64[ns, UTC] | End time of a task. |
16
16
  | `subtype` | string | Subtype of a task. |
17
17
  | `tags` | List[str] | List of descriptive tags. |
18
+ | `image` | blob | Raw binary data related to an image. |
18
19
  | `telemetry_summary.duration_sec` | float | Task duration (seconds). |
19
20
  | `telemetry_summary.cpu.percent_all_diff` | float | Difference in overall CPU utilization percentage across all cores between task end and start.|
20
21
  | `telemetry_summary.cpu.user_time_diff` | float | Difference average per core CPU user time ( seconds ) between task start and end times.|
@@ -27,6 +28,17 @@ COMMON_TASK_FIELDS = """
27
28
  DF_FORM = "The user has a pandas DataFrame called `df`, created from flattened task objects using `pd.json_normalize`."
28
29
 
29
30
 
31
+ def get_example_values_prompt(example_values):
32
+ values_prompt = f"""
33
+ Now, this other dictionary below provides type (t), up to 3 example values (v), and, for lists, shape (s) and element type (et) for each field.
34
+ Field names do not include `used.` or `generated.` They represent the unprefixed form shared across roles. String values may be truncated if they exceed the length limit.
35
+ ```python
36
+ {example_values}
37
+ ```
38
+ """
39
+ return values_prompt
40
+
41
+
30
42
  def get_df_schema_prompt(dynamic_schema, example_values):
31
43
  schema_prompt = f"""
32
44
  ## DATAFRAME STRUCTURE
@@ -52,14 +64,7 @@ def get_df_schema_prompt(dynamic_schema, example_values):
52
64
  ---
53
65
  """
54
66
 
55
- values_prompt = f"""
56
- Now, this other dictionary below provides type (t), up to 3 example values (v), and, for lists, shape (s) and element type (et) for each field.
57
- Field names do not include `used.` or `generated.` They represent the unprefixed form shared across roles. String values may be truncated if they exceed the length limit.
58
- ```python
59
- {example_values}
60
- ```
61
- """
62
-
67
+ values_prompt = get_example_values_prompt(example_values)
63
68
  # values_prompt = ""
64
69
  prompt = schema_prompt + values_prompt
65
70
  return prompt
@@ -221,7 +226,7 @@ def generate_pandas_code_prompt(query: str, dynamic_schema, example_values):
221
226
  f"{JOB}"
222
227
  f"{DF_FORM}"
223
228
  f"{get_df_schema_prompt(dynamic_schema, example_values)}" # main tester
224
- # f"{QUERY_GUIDELINES}" # main tester
229
+ f"{QUERY_GUIDELINES}" # main tester
225
230
  f"{FEW_SHOTS}" # main tester
226
231
  f"{OUTPUT_FORMATTING}"
227
232
  "User Query:"
@@ -230,9 +235,16 @@ def generate_pandas_code_prompt(query: str, dynamic_schema, example_values):
230
235
  return prompt
231
236
 
232
237
 
233
- def dataframe_summarizer_context(code, reduced_df, query) -> str:
238
+ def dataframe_summarizer_context(code, reduced_df, dynamic_schema, example_values, query) -> str:
239
+ job = "You are a Workflow Provenance Specialist analyzing a DataFrame that was obtained to answer a query."
240
+
241
+ if "image" in reduced_df.columns:
242
+ reduced_df = reduced_df.drop(columns=["image"])
243
+
234
244
  prompt = f"""
235
- You are a Workflow Provenance Specialist analyzing a DataFrame that was obtained to answer a query. Given:
245
+ {job}
246
+
247
+ Given:
236
248
 
237
249
  **User Query**:
238
250
  {query}
@@ -240,19 +252,26 @@ def dataframe_summarizer_context(code, reduced_df, query) -> str:
240
252
  **Query_Code**:
241
253
  {code}
242
254
 
243
- **Reduced DataFrame** (rows sampled from full result):
255
+ **Reduced DataFrame `df` contents** (rows sampled from full result):
244
256
  {reduced_df}
245
257
 
246
- Your task is to:
247
- 1. Analyze the DataFrame values and columns for any meaningful or notable information.
248
- 2. Compare the query_code with the data content to understand what the result represents. THIS IS A REDUCED DATAFRAME, the original dataframe, used to answer the query, may be much bigger. IT IS ALREADY KNOWN! Do not need to restate this.
249
- 3. Provide a concise and direct answer to the user query. Your final response to the query should be within ```text .
258
+ **Original df (before reduction) had this schema:
259
+ {get_df_schema_prompt(dynamic_schema, example_values)}
260
+
261
+ Your task is to find a concise and direct answer as an English sentence to the user query.
262
+
263
+ Only if the answer to the query is complex, provide more explanation by:
264
+ 1. Analyzing the DataFrame values and columns for any meaningful or notable information.
265
+ 2. Comparing the query_code with the data content to understand what the result represents. THIS IS A REDUCED DATAFRAME, the original dataframe, used to answer the query, may be much bigger. IT IS ALREADY KNOWN! Do not need to restate this.
266
+ 3. If it makes sense, provide information beyond the recorded provenance, but state it clearly that you are inferring it.
267
+
268
+ In the end, conclude by giving your concise answer as follows: **Response**: <YOUR ANSWER>
250
269
 
251
270
  Note that the user should not know that this is a reduced dataframe.
252
-
253
271
  Keep your response short and focused.
254
272
 
255
273
  """
274
+
256
275
  return prompt
257
276
 
258
277
 
@@ -74,7 +74,7 @@ def prompt_handler(message: str) -> ToolResult:
74
74
  TextContent
75
75
  The AI response or routing feedback.
76
76
  """
77
- df_key_words = {"save", "result = df", "reset context"}
77
+ df_key_words = ["df", "save", "result = df", "reset context"]
78
78
  for key in df_key_words:
79
79
  if key in message:
80
80
  return run_df_query(llm=None, query=message, plot=False)
@@ -294,6 +294,8 @@ def generate_result_df(llm, query: str, dynamic_schema, example_values, df, atte
294
294
  >>> generate_result_df(llm, "bad query", schema, examples, df, attempt_fix=False)
295
295
  ToolResult(code=405, result="Failed to parse this as Python code: ...")
296
296
  """
297
+ if llm is None:
298
+ llm = build_llm_model()
297
299
  try:
298
300
  prompt = generate_pandas_code_prompt(query, dynamic_schema, example_values)
299
301
  response = llm(prompt)
@@ -351,7 +353,14 @@ def generate_result_df(llm, query: str, dynamic_schema, example_values, df, atte
351
353
  summary, summary_error = None, None
352
354
  if summarize:
353
355
  try:
354
- tool_result = summarize_result(llm, result_code, result_df, query)
356
+ tool_result = summarize_result(
357
+ llm,
358
+ result_code,
359
+ result_df,
360
+ query,
361
+ dynamic_schema,
362
+ example_values,
363
+ )
355
364
  if tool_result.is_success():
356
365
  return_code = 301
357
366
  summary = tool_result.result
@@ -570,7 +579,14 @@ def extract_or_fix_json_code(llm, raw_text) -> ToolResult:
570
579
 
571
580
 
572
581
  @mcp_flowcept.tool()
573
- def summarize_result(llm, code, result, query: str) -> ToolResult:
582
+ def summarize_result(
583
+ llm,
584
+ code,
585
+ result,
586
+ query: str,
587
+ dynamic_schema,
588
+ example_values,
589
+ ) -> ToolResult:
574
590
  """
575
591
  Summarize the pandas result with local reduction for large DataFrames.
576
592
  - For wide DataFrames, selects top columns based on variance and uniqueness.
@@ -578,7 +594,7 @@ def summarize_result(llm, code, result, query: str) -> ToolResult:
578
594
  - Constructs a detailed prompt for the LLM with original column context.
579
595
  """
580
596
  summarized_df = summarize_df(result, code)
581
- prompt = dataframe_summarizer_context(code, summarized_df, query)
597
+ prompt = dataframe_summarizer_context(code, summarized_df, dynamic_schema, example_values, query)
582
598
  try:
583
599
  response = llm(prompt)
584
600
  return ToolResult(code=201, result=response)
@@ -137,7 +137,6 @@ def summarize_task(task: Dict, thresholds: Dict = None, logger=None) -> Dict:
137
137
  "agent_id",
138
138
  "campaign_id",
139
139
  "subtype",
140
- "custom_metadata",
141
140
  ]:
142
141
  value = _safe_get(task, key)
143
142
  if value is not None:
@@ -146,7 +145,14 @@ def summarize_task(task: Dict, thresholds: Dict = None, logger=None) -> Dict:
146
145
  else:
147
146
  task_summary[key] = value
148
147
 
149
- # Special handling for timestamp field
148
+ # Adding image column if data is image. This is to handle special cases when there is an image associated to
149
+ # a provenance task.
150
+ if "data" in task:
151
+ if "custom_metadata" in task:
152
+ if "image" in task["custom_metadata"].get("mime_type", ""):
153
+ task_summary["image"] = task["data"]
154
+
155
+ # Special handling for timestamp field
150
156
  try:
151
157
  time_keys = ["started_at", "ended_at"]
152
158
  for time_key in time_keys:
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.9.2"
7
+ __version__ = "0.9.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowcept
3
- Version: 0.9.2
3
+ Version: 0.9.3
4
4
  Summary: Capture and query workflow provenance data using data observability
5
5
  Author: Oak Ridge National Laboratory
6
6
  License-Expression: MIT
@@ -1,26 +1,26 @@
1
1
  flowcept/__init__.py,sha256=urpwIEJeikV0P6ORXKsM5Lq4o6wCwhySS9A487BYGy4,2241
2
2
  flowcept/cli.py,sha256=eVnUrmZtVhZ1ldRMGB1QsqBzNC1Pf2CX33efnlaZ4gs,22842
3
3
  flowcept/configs.py,sha256=xw9cdk-bDkR4_bV2jBkDCe9__na9LKJW5tUG32by-m4,8216
4
- flowcept/version.py,sha256=vKyazpFciSPMlst6m2HH-9RdZcbRHHnKT0jk92I-APc,306
4
+ flowcept/version.py,sha256=p-n2RnT_4VKaEani8rrxiu2EmdHh2opviguHZlI3gso,306
5
5
  flowcept/agents/__init__.py,sha256=8eeD2CiKBtHiDsWdrHK_UreIkKlTq4dUbhHDyzw372o,175
6
6
  flowcept/agents/agent_client.py,sha256=UiBQkC9WE2weLZR2OTkEOEQt9-zqQOkPwRA17HfI-jk,2027
7
7
  flowcept/agents/agents_utils.py,sha256=Az5lvWTsBHs_3sWWwy7jSdDjNn-PvZ7KmYd79wxvdyU,6666
8
8
  flowcept/agents/dynamic_schema_tracker.py,sha256=TsmXRRkyUkqB-0bEgmeqSms8xj1tMMJeYvjoaO2mtwI,6829
9
9
  flowcept/agents/flowcept_agent.py,sha256=1sidjnNMdG0S6lUKBvml7ZfIb6o3u7zc6HNogsJbl9g,871
10
- flowcept/agents/flowcept_ctx_manager.py,sha256=-WYulunHE62w61z8cy3u7TEnvgV1hflNEXsnm8YxwFw,6840
10
+ flowcept/agents/flowcept_ctx_manager.py,sha256=8uICi7KDQDbiCYdNSrWGBYQMwwyF3HMbgKY4mPISXuo,7013
11
11
  flowcept/agents/gui/__init__.py,sha256=Qw9YKbAzgZqBjMQGnF7XWmfUo0fivtkDISQRK3LA3gU,113
12
12
  flowcept/agents/gui/agent_gui.py,sha256=8sTG3MjWBi6oc4tnfHa-duTBXWEE6RBxBE5uHooGkzI,2501
13
- flowcept/agents/gui/gui_utils.py,sha256=Qex0G9Asgb_UnLTySB8cYNEEy9ZnmLYnLddbornoDcI,7861
13
+ flowcept/agents/gui/gui_utils.py,sha256=61JpFKu-yd7luWVBW6HQYd3feOmupR01tYsZxl804No,9517
14
14
  flowcept/agents/llms/__init__.py,sha256=kzOaJic5VhMBnGvy_Fr5C6sRKVrRntH1ZnYz7f5_4-s,23
15
15
  flowcept/agents/llms/claude_gcp.py,sha256=fzz7235DgzVueuFj5odsr93jWtYHpYlXkSGW1kmmJwU,4915
16
16
  flowcept/agents/llms/gemini25.py,sha256=VARrjb3tITIh3_Wppmocp_ocSKVZNon0o0GeFEwTnTI,4229
17
17
  flowcept/agents/prompts/__init__.py,sha256=7ICsNhLYzvPS1esG3Vg519s51b1c4yN0WegJUb6Qvww,26
18
18
  flowcept/agents/prompts/general_prompts.py,sha256=q0KmR2QYEtBqQOssoF8W5EhZidqC59wL6XFVjF_dbWQ,3675
19
- flowcept/agents/prompts/in_memory_query_prompts.py,sha256=oWvZQNUHBBrGq-f94ulhIZW4bkkze02EzAuHY5640QM,17934
19
+ flowcept/agents/prompts/in_memory_query_prompts.py,sha256=o5FXZqaOnIZ9qxlzGN1pT_J7_ZkKQhz0MAD8cVezq-Y,18736
20
20
  flowcept/agents/tools/__init__.py,sha256=Xqz2E4-LL_7DDcm1XYJFx2f5RdAsjeTpOJb_DPC7xyc,27
21
- flowcept/agents/tools/general_tools.py,sha256=Dw1vYNzVUp8dIB48KFPNxGenERoS8UqJj0HIEfhjQeA,2752
21
+ flowcept/agents/tools/general_tools.py,sha256=_S_oCW2xMGc1MAQuy40SHFc3bpmql9v6eH8Nayq4oy8,2758
22
22
  flowcept/agents/tools/in_memory_queries/__init__.py,sha256=K8-JI_lXUgquKkgga8Nef8AntGg_logQtjjQjaEE7yI,39
23
- flowcept/agents/tools/in_memory_queries/in_memory_queries_tools.py,sha256=hrVal1ktf6lvBmVWS7cR_lQy4cIz7ZNYLC-MN61WNRg,25450
23
+ flowcept/agents/tools/in_memory_queries/in_memory_queries_tools.py,sha256=pbwFHmt_vMEGSG4a7tC-KuVRpibkKKf4cbPpQSKAL9w,25736
24
24
  flowcept/agents/tools/in_memory_queries/pandas_agent_utils.py,sha256=xi69oywlGb6IUkhQKXoKoswYuWK5FyiWHy2MnRjTzds,9055
25
25
  flowcept/analytics/__init__.py,sha256=46q-7vsHq_ddPNrzNnDgEOiRgvlx-5Ggu2ocyROMV0w,641
26
26
  flowcept/analytics/analytics_utils.py,sha256=FRJdBtQa7Hrk2oR_FFhmhmMf3X6YyZ4nbH5RIYh7KL4,8753
@@ -31,7 +31,7 @@ flowcept/commons/autoflush_buffer.py,sha256=Ohy_RNbq6BXn0_R83OL5iaTgGPmV8cT1moIR
31
31
  flowcept/commons/flowcept_logger.py,sha256=0asRucrDMeRXvsdhuCmH6lWO7lAt_Z5o5uW7rrQhcjc,1857
32
32
  flowcept/commons/query_utils.py,sha256=3tyK5VYA10iDtmtzNwa8OQGn93DBxsu6rTjHDphftSc,2208
33
33
  flowcept/commons/settings_factory.py,sha256=bMTjgXRfb5HsL2lPnLfem-9trqELbNWE04Ie7lSlxYM,1731
34
- flowcept/commons/task_data_preprocess.py,sha256=yxLOq3PhfJYDeOUrbBzLc-x7zDrKqB30pwk1nIqtdgo,13552
34
+ flowcept/commons/task_data_preprocess.py,sha256=bJed8Jbo4Mxk6aRVt3sCn4_KxfV5jWXwAIQWwuqHm3U,13846
35
35
  flowcept/commons/utils.py,sha256=gF6ENWlTpR2ZSw3yVNPNBTVzSpcgy-WuzYzwWSXXsug,9252
36
36
  flowcept/commons/vocabulary.py,sha256=_GzHJ1wSYJlLsu_uu1Am6N3zvc59S4FCuT5yp7lynPw,713
37
37
  flowcept/commons/daos/__init__.py,sha256=RO51svfHOg9naN676zuQwbj_RQ6IFHu-RALeefvtwwk,23
@@ -93,9 +93,9 @@ flowcept/instrumentation/flowcept_loop.py,sha256=7hkcolXxbwwccNzoSbAeCCEu02i4zT3
93
93
  flowcept/instrumentation/flowcept_task.py,sha256=EmKODpjl8usNklKSVmsKYyCa6gC_QMqKhAr3DKaw44s,8199
94
94
  flowcept/instrumentation/flowcept_torch.py,sha256=kkZQRYq6cDBpdBU6J39_4oKRVkhyF3ODlz8ydV5WGKw,23455
95
95
  flowcept/instrumentation/task_capture.py,sha256=1g9EtLdqsTB0RHsF-eRmA2Xh9l_YqTd953d4v89IC24,8287
96
- resources/sample_settings.yaml,sha256=NxiDXh_IAVBsHdxyhB2U-v212hGPLtHTqAVE6_3GyJ0,6756
97
- flowcept-0.9.2.dist-info/METADATA,sha256=H91pextdVg1DgvI_HPgt4CnRJeH4UmrC5dsZpLwOAiY,31424
98
- flowcept-0.9.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
- flowcept-0.9.2.dist-info/entry_points.txt,sha256=i8q67WE0201rVxYI2lyBtS52shvgl93x2Szp4q8zMlw,47
100
- flowcept-0.9.2.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
101
- flowcept-0.9.2.dist-info/RECORD,,
96
+ resources/sample_settings.yaml,sha256=Y2RLR4aZS434yQheN3-lqT1i90vj0YeF3S44Dl_voZM,6756
97
+ flowcept-0.9.3.dist-info/METADATA,sha256=au_dgUmmQMR38AKSb2dL8IEbVhmATxdg3G9y-kF9jOs,31424
98
+ flowcept-0.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
+ flowcept-0.9.3.dist-info/entry_points.txt,sha256=i8q67WE0201rVxYI2lyBtS52shvgl93x2Szp4q8zMlw,47
100
+ flowcept-0.9.3.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
101
+ flowcept-0.9.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
- flowcept_version: 0.9.2 # Version of the Flowcept package. This setting file is compatible with this version.
1
+ flowcept_version: 0.9.3 # 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.