fastworkflow 2.8.17__py3-none-any.whl → 2.8.19__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.
@@ -416,7 +416,10 @@ class CommandDirectory(BaseModel):
416
416
  parts = os.path.splitext(rel_path)[0].split(os.sep)
417
417
  qualified_name = "/".join(parts) if len(parts) > 1 else parts[0]
418
418
  discovered_commands.add(qualified_name)
419
-
419
+
420
+ if not discovered_commands:
421
+ raise RuntimeError("No core commands discovered in internal workflow: {internal_wf_path}")
422
+
420
423
  return discovered_commands
421
424
 
422
425
  @classmethod
@@ -581,9 +584,7 @@ def get_cached_command_directory(workflow_folderpath: str) -> CommandDirectory:
581
584
 
582
585
  # Fast-path: load JSON if it is newer than any source file
583
586
  if cache_file.exists() and cache_file.stat().st_mtime > latest_src_mtime:
584
- with contextlib.suppress(Exception): # Suppress errors during deserialization (e.g., corrupted cache)
585
- # If deserialization fails, we'll just rebuild.
586
- return CommandDirectory.model_validate_json(cache_file.read_text())
587
+ return CommandDirectory.model_validate_json(cache_file.read_text())
587
588
 
588
589
  # (Re)build and persist
589
590
  directory = CommandDirectory.load(workflow_folderpath)
@@ -26,6 +26,7 @@ from fastworkflow import ModuleType
26
26
  from fastworkflow.command_directory import CommandDirectory, UtteranceMetadata, get_cached_command_directory
27
27
  from fastworkflow.command_context_model import CommandContextModel
28
28
  from fastworkflow.utils import python_utils
29
+ from fastworkflow.utils.logging import logger
29
30
 
30
31
 
31
32
  class RoutingDefinition(BaseModel):
@@ -237,36 +238,36 @@ class RoutingDefinition(BaseModel):
237
238
  in the format 'ContextName/command_name'. This method ensures these qualified names
238
239
  are properly handled when building the routing definition.
239
240
  """
240
- try:
241
- # Use cached command directory to avoid repeated filesystem scanning
242
- command_directory = get_cached_command_directory(workflow_folderpath)
243
- context_model = CommandContextModel.load(workflow_folderpath)
244
-
245
- # Use dynamically discovered core commands
246
- core_commands = command_directory.core_command_names
247
-
248
- resolved_contexts = {}
249
- for context_name in context_model._command_contexts:
250
- # Get commands for this context from the context model
251
- context_commands = context_model.commands(context_name)
252
-
253
- # Add core commands to every context
254
- resolved_contexts[context_name] = sorted(set(context_commands) | set(core_commands))
255
-
256
- # Ensure global context '*' also exists with core commands (if not in model)
257
- if '*' not in resolved_contexts:
258
- resolved_contexts['*'] = sorted(core_commands)
259
- except Exception as e:
260
- # Handle errors gracefully for tests expecting this behavior
261
- # This matches the behavior of the original CommandRouter
262
- if "_commands" not in str(e) and "does not exist" not in str(e):
263
- # Re-raise unexpected errors
264
- raise
241
+ # Use cached command directory to avoid repeated filesystem scanning
242
+ command_directory = get_cached_command_directory(workflow_folderpath)
243
+ context_model = CommandContextModel.load(workflow_folderpath)
244
+
245
+ # Use dynamically discovered core commands
246
+ core_commands = command_directory.core_command_names
247
+ logger.debug(f"Core commands: {str(core_commands)}, Workflow folderpath {workflow_folderpath}")
248
+
249
+ resolved_contexts = {}
250
+ for context_name in context_model._command_contexts:
251
+ # Get commands for this context from the context model
252
+ context_commands = context_model.commands(context_name)
253
+
254
+ # Add core commands to every context
255
+ resolved_contexts[context_name] = sorted(set(context_commands) | set(core_commands))
256
+
257
+ # Ensure global context '*' also exists with core commands (if not in model)
258
+ if '*' not in resolved_contexts:
259
+ resolved_contexts['*'] = sorted(core_commands)
260
+ # except Exception as e:
261
+ # # Handle errors gracefully for tests expecting this behavior
262
+ # # This matches the behavior of the original CommandRouter
263
+ # if "_commands" not in str(e) and "does not exist" not in str(e):
264
+ # # Re-raise unexpected errors
265
+ # raise
265
266
 
266
267
  # For missing directories, return an empty definition
267
- command_directory = CommandDirectory(workflow_folderpath=workflow_folderpath)
268
- context_model = CommandContextModel(_workflow_path=workflow_folderpath, _command_contexts={})
269
- resolved_contexts = {"*": []}
268
+ # command_directory = CommandDirectory(workflow_folderpath=workflow_folderpath)
269
+ # context_model = CommandContextModel(_workflow_path=workflow_folderpath, _command_contexts={})
270
+ # resolved_contexts = {"*": []}
270
271
 
271
272
  routing_definition = cls(
272
273
  workflow_folderpath=workflow_folderpath,
@@ -275,10 +276,12 @@ class RoutingDefinition(BaseModel):
275
276
  contexts=resolved_contexts,
276
277
  )
277
278
 
278
- with contextlib.suppress(Exception):
279
- # Only save if we were able to build successfully
280
- if resolved_contexts != {"*": []}:
281
- routing_definition.save()
279
+ # Only save if we were able to build successfully
280
+ if resolved_contexts != {"*": []}:
281
+ routing_definition.save()
282
+ else:
283
+ logger.error(f"Could not build command_routing_defintion.json for workflow folderpath {workflow_folderpath}")
284
+
282
285
  return routing_definition
283
286
 
284
287
  def scan(self, use_cache=True):
@@ -1069,13 +1069,10 @@ def train(workflow: fastworkflow.Workflow):
1069
1069
 
1070
1070
 
1071
1071
  text = "list commands"
1072
- try:
1073
- result = predict_single_sentence(pipeline, text, label_path)
1074
- print(f"Predicted label: {result['label']}")
1075
- print(f"Confidence: {result['confidence']:.4f}")
1076
- print(f"Used DistilBERT: {'Yes' if result['used_distil'] else 'No'}")
1077
- except ValueError as e:
1078
- print(f"Error: {e}")
1072
+ result = predict_single_sentence(pipeline, text, label_path)
1073
+ print(f"Predicted label: {result['label']}")
1074
+ print(f"Confidence: {result['confidence']:.4f}")
1075
+ print(f"Used DistilBERT: {'Yes' if result['used_distil'] else 'No'}")
1079
1076
 
1080
1077
  # End of context loop
1081
1078
  return None
fastworkflow/workflow.py CHANGED
@@ -297,7 +297,7 @@ class Workflow:
297
297
  )
298
298
  shutil.rmtree(sessiondb_folderpath, ignore_errors=True)
299
299
  except OSError as e:
300
- logger.error(f"Error closing session: {e}")
300
+ logger.error(f"Error closing session: {e}", stack_info=True)
301
301
  return False
302
302
 
303
303
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastworkflow
3
- Version: 2.8.17
3
+ Version: 2.8.19
4
4
  Summary: A framework for rapidly building large-scale, deterministic, interactive workflows with a fault-tolerant, conversational UX
5
5
  License: Apache-2.0
6
6
  Keywords: fastworkflow,ai,workflow,llm,openai
@@ -33,10 +33,10 @@ fastworkflow/cache_matching.py,sha256=WoSQ7QuVGqOnecsIIdwb3A6gBpt0OJdSzx_a51nHoF
33
33
  fastworkflow/chat_session.py,sha256=lEpJmU_2a-4pB4QR7wACl8jHWZls1ROtQGgdVObY3BA,12308
34
34
  fastworkflow/cli.py,sha256=SVIvd-GEfwAdWQT7om5DC9MC5wLivP_bXlgMF0T5Cjw,21736
35
35
  fastworkflow/command_context_model.py,sha256=nWxLP3TR7WJr3yWCedqcdFOxo_kwae_mS3VRN2cOmK8,13437
36
- fastworkflow/command_directory.py,sha256=gnt1n8IO8ZZSuxkzwN6kZlkCC6NVK7UzFEVBZeFm-DI,27189
36
+ fastworkflow/command_directory.py,sha256=S-QRHW66VHH10YIpm3-dQs8fvtXM5VKFyBLocGkduF8,27134
37
37
  fastworkflow/command_executor.py,sha256=bKqOHBEVhCunE3B-zh6DNLERUiSmEiVJdfEoVVUq-zM,6412
38
38
  fastworkflow/command_interfaces.py,sha256=PWIKlcp0G8nmYl0vkrg1o6QzJL0pxXkfrn1joqTa0eU,460
39
- fastworkflow/command_routing.py,sha256=BtBPeYRVIUgHKhgGJpOirkZAyGjBEQuaZv5qBT0hEMc,15557
39
+ fastworkflow/command_routing.py,sha256=uOGNiUjeSGTRTc3AqQoUnXjisiG5yIhHHDpbLa2zyPM,15736
40
40
  fastworkflow/docs/context_modules_prd.txt,sha256=9wvs3LgNoIVXAczo1sXBIV4YmFqVhzC2ja1T3K7FG04,2199
41
41
  fastworkflow/examples/fastworkflow.env,sha256=5yQTfQpK99TR5dLwKVOwFatuC1G73Rkng2hv2IjX6cg,645
42
42
  fastworkflow/examples/fastworkflow.passwords.env,sha256=zucqjXFPsp-SRtDBNn_v7h_N1l8uNBcMEHqQoIcQa6M,355
@@ -122,7 +122,7 @@ fastworkflow/examples/todo_list/application/todo_manager.py,sha256=0WBtJ04O9tU-l
122
122
  fastworkflow/examples/todo_list/context_hierarchy_model.json,sha256=S_MoRhdj2o9_VhAdYpO64VIhlAUwFlWfvSs9T_7FPYA,219
123
123
  fastworkflow/examples/todo_list/startup_action.json,sha256=gj0-B4CqTYCs8OwHKhTu95H4uZbLsDf1th06IFfNXVs,75
124
124
  fastworkflow/mcp_server.py,sha256=Q1_KBwXg5EaJMz232OHNjH1fRg7BuZcJ7T7872qfDco,7783
125
- fastworkflow/model_pipeline_training.py,sha256=S3Dm9JywKh3KYqwiKV-FJgg-YGpBn6iRUvRtdHOi9Ts,44320
125
+ fastworkflow/model_pipeline_training.py,sha256=St4Qgcf6Yq-xfX2txJ9S2mL1jRTO9g3OMvJ06vnzLQ4,44226
126
126
  fastworkflow/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
127
  fastworkflow/run/__main__.py,sha256=uFENKUAPEJKOH5o7KzYtwkyKSI1sDFEwx1TNodeLVnA,5789
128
128
  fastworkflow/run_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -145,9 +145,9 @@ fastworkflow/utils/parameterize_func_decorator.py,sha256=V6YJnishWRCdwiBQW6P17hm
145
145
  fastworkflow/utils/pydantic_model_2_dspy_signature_class.py,sha256=w1pvl8rJq48ulFwaAtBgfXYn_SBIDBgq1aLMUg1zJn8,12875
146
146
  fastworkflow/utils/python_utils.py,sha256=Lt6P8lBMbLuLZaP9gd_7Kl7UvSPLm-NKPN6cPUdn53w,8194
147
147
  fastworkflow/utils/signatures.py,sha256=4ksF-65Q-22ZR_SW8O_cv5RhKKk0ecmWgykoAGKxr-k,19957
148
- fastworkflow/workflow.py,sha256=zHsA67IMlHAhpgM2CN96G_KsU_eMVXJf7axZ2zBBdhU,16436
149
- fastworkflow-2.8.17.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
150
- fastworkflow-2.8.17.dist-info/METADATA,sha256=tQ-9OYB6QtLKInCWPRQK-kmEpT14VhgRiApMUm-n1Ms,15387
151
- fastworkflow-2.8.17.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
152
- fastworkflow-2.8.17.dist-info/entry_points.txt,sha256=m8HqoPzCyaZLAx-V5X8MJgw3Lx3GiPDlxNEZ7K-Gb-U,54
153
- fastworkflow-2.8.17.dist-info/RECORD,,
148
+ fastworkflow/workflow.py,sha256=URYIgoBObL4Ota1BMdW4kqmepi6E_tCoZBXCFS33qOw,16453
149
+ fastworkflow-2.8.19.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
150
+ fastworkflow-2.8.19.dist-info/METADATA,sha256=hJYSJqr5_wxUpwpV0I-Msv-7ifPIyN58p6qosbDeYgk,15387
151
+ fastworkflow-2.8.19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
152
+ fastworkflow-2.8.19.dist-info/entry_points.txt,sha256=m8HqoPzCyaZLAx-V5X8MJgw3Lx3GiPDlxNEZ7K-Gb-U,54
153
+ fastworkflow-2.8.19.dist-info/RECORD,,