fastworkflow 2.17.12__py3-none-any.whl → 2.17.14__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.
@@ -473,6 +473,10 @@ class ChatSession:
473
473
  if os.path.exists("action.jsonl"):
474
474
  os.remove("action.jsonl")
475
475
 
476
+ # store the message as 'raw_user_input' in workflow_context. This is useful in agentic mode
477
+ # when command implementations want to get the exact message that user entered (no refinement)
478
+ self._current_workflow.context['raw_user_message'] = message
479
+
476
480
  refined_user_query = self._refine_user_query(message, self.conversation_history)
477
481
 
478
482
  from fastworkflow.workflow_agent import build_query_with_next_steps
@@ -28,27 +28,26 @@ class IntentClarificationAgentSignature(dspy.Signature):
28
28
  error_message = dspy.InputField(desc="The intent detection error message from the workflow.")
29
29
  agent_inputs = dspy.InputField(desc="The original inputs to the workflow agent.")
30
30
  agent_trajectory = dspy.InputField(desc="The workflow agent's trajectory showing all actions taken so far leading to this error.")
31
- suggested_commands_metadata = dspy.InputField(desc="Metadata for suggested commands (for ambiguity clarification), or empty string (for misunderstanding - use show_available_commands tool instead).")
32
31
  clarified_command = dspy.OutputField(desc="The complete command with correct command name AND all original parameters preserved.")
33
32
 
34
33
 
35
- def _show_available_commands(chat_session: fastworkflow.ChatSession) -> str:
36
- """
37
- Show available commands to help resolve intent detection errors.
34
+ # def _show_available_commands(chat_session: fastworkflow.ChatSession) -> str:
35
+ # """
36
+ # Show available commands to help resolve intent detection errors.
38
37
 
39
- Args:
40
- chat_session: The chat session instance
38
+ # Args:
39
+ # chat_session: The chat session instance
41
40
 
42
- Returns:
43
- List of available commands
44
- """
41
+ # Returns:
42
+ # List of available commands
43
+ # """
45
44
 
46
- current_workflow = chat_session.get_active_workflow()
47
- return CommandMetadataAPI.get_command_display_text(
48
- subject_workflow_path=current_workflow.folderpath,
49
- cme_workflow_path=fastworkflow.get_internal_workflow_path("command_metadata_extraction"),
50
- active_context_name=current_workflow.current_command_context_name,
51
- )
45
+ # current_workflow = chat_session.get_active_workflow()
46
+ # return CommandMetadataAPI.get_command_display_text(
47
+ # subject_workflow_path=current_workflow.folderpath,
48
+ # cme_workflow_path=fastworkflow.get_internal_workflow_path("command_metadata_extraction"),
49
+ # active_context_name=current_workflow.current_command_context_name,
50
+ # )
52
51
 
53
52
 
54
53
  def _ask_user_for_clarification(
@@ -103,11 +102,11 @@ def initialize_intent_clarification_agent(
103
102
  if not chat_session:
104
103
  raise ValueError("chat_session cannot be null")
105
104
 
106
- def show_available_commands() -> str:
107
- """
108
- Show all available commands to help resolve intent ambiguity.
109
- """
110
- return _show_available_commands(chat_session)
105
+ # def show_available_commands() -> str:
106
+ # """
107
+ # Show all available commands to help resolve intent ambiguity.
108
+ # """
109
+ # return _show_available_commands(chat_session)
111
110
 
112
111
  def ask_user(clarification_request: str) -> str:
113
112
  """
@@ -121,7 +120,7 @@ def initialize_intent_clarification_agent(
121
120
 
122
121
  # Limited tool set for intent detection errors
123
122
  tools = [
124
- show_available_commands,
123
+ # show_available_commands,
125
124
  ask_user,
126
125
  ]
127
126
 
@@ -33,37 +33,6 @@ def _what_can_i_do(chat_session_obj: fastworkflow.ChatSession) -> str:
33
33
  active_context_name=current_workflow.current_command_context_name,
34
34
  )
35
35
 
36
- # def _clarify_ambiguous_intent(
37
- # correct_command_name: str,
38
- # chat_session_obj: fastworkflow.ChatSession) -> str:
39
- # """
40
- # Call this tool ONLY in the intent detection error state (ambiguous or misunderstood intent) to provide the exact command name.
41
- # The intent detection error message will list the command names to pick from.
42
- # """
43
- # return _execute_workflow_query(correct_command_name, chat_session_obj = chat_session_obj)
44
-
45
- # def _provide_missing_or_corrected_parameters(
46
- # missing_or_corrected_parameter_values: list[str|int|float|bool],
47
- # chat_session_obj: fastworkflow.ChatSession) -> str:
48
- # """
49
- # Call this tool ONLY in the parameter extraction error state to provide missing or corrected parameter values.
50
- # Missing parameter values may be found in the user query, or information already available, or by aborting and executing a different command (refer to the optional 'available_from' hint for guidance on appropriate commands to use to get the information).
51
- # If the error message indicates parameter values are improperly formatted, correct using your internal knowledge and command metadata information.
52
- # """
53
- # if missing_or_corrected_parameter_values:
54
- # command = ', '.join(missing_or_corrected_parameter_values)
55
- # else:
56
- # return "Provide missing or corrected parameter values or abort"
57
-
58
- # return _execute_workflow_query(command, chat_session_obj = chat_session_obj)
59
-
60
- # def _abort_current_command_to_exit_parameter_extraction_error_state(
61
- # chat_session_obj: fastworkflow.ChatSession) -> str:
62
- # """
63
- # Call this tool ONLY in the parameter extraction error state when you want to get out of the parameter extraction error state and execute a different command.
64
- # """
65
- # return
66
-
67
36
  def _intent_misunderstood(
68
37
  chat_session_obj: fastworkflow.ChatSession) -> str:
69
38
  """
@@ -142,6 +111,10 @@ def _execute_workflow_query(command: str, chat_session_obj: fastworkflow.ChatSes
142
111
  # Handle intent ambiguity clarification state with specialized agent
143
112
  if nlu_stage == fastworkflow.NLUPipelineStage.INTENT_AMBIGUITY_CLARIFICATION:
144
113
  if intent_agent := chat_session_obj.intent_clarification_agent:
114
+ from fastworkflow.utils.chat_adapter import CommandsSystemPreludeAdapter
115
+ # Use CommandsSystemPreludeAdapter specifically for workflow agent calls
116
+ agent_adapter = CommandsSystemPreludeAdapter()
117
+
145
118
  # Get suggested commands from intent detection system
146
119
  from fastworkflow._workflows.command_metadata_extraction.intent_detection import CommandNamePrediction
147
120
  predictor = CommandNamePrediction(cme_workflow)
@@ -164,13 +137,13 @@ def _execute_workflow_query(command: str, chat_session_obj: fastworkflow.ChatSes
164
137
  agent_trajectory = workflow_tool_agent.current_trajectory if workflow_tool_agent else {}
165
138
 
166
139
  lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
167
- with dspy.context(lm=lm):
140
+ with dspy.context(lm=lm, adapter=agent_adapter):
168
141
  result = intent_agent(
169
142
  original_command=command,
170
143
  error_message=response_text,
171
144
  agent_inputs=agent_inputs,
172
145
  agent_trajectory=agent_trajectory,
173
- suggested_commands_metadata=suggested_commands_metadata
146
+ available_commands=suggested_commands_metadata # Note that this is not part of the signature. It is extra metadata that will be picked up by the CommandsSystemPreludeAdapter
174
147
  )
175
148
  # The clarified command should have the correct name with all original parameters
176
149
  clarified_cmd = result.clarified_command if hasattr(result, 'clarified_command') else str(result)
@@ -196,7 +169,6 @@ def _execute_workflow_query(command: str, chat_session_obj: fastworkflow.ChatSes
196
169
  error_message=response_text,
197
170
  agent_inputs=agent_inputs,
198
171
  agent_trajectory=agent_trajectory,
199
- suggested_commands_metadata=""
200
172
  )
201
173
 
202
174
  clarified_cmd = result.clarified_command if hasattr(result, 'clarified_command') else str(result)
@@ -212,34 +184,13 @@ def _execute_workflow_query(command: str, chat_session_obj: fastworkflow.ChatSes
212
184
  abort_confirmation = _execute_workflow_query('abort', chat_session_obj=chat_session_obj)
213
185
  return f'{response_text}\n{abort_confirmation}'
214
186
 
187
+ # Clean up the context flag after command execution
188
+ workflow = chat_session_obj.get_active_workflow()
189
+ if workflow and "is_user_command" in workflow.context:
190
+ del workflow.context["is_user_command"]
191
+
215
192
  return response_text
216
193
 
217
- # def _missing_information_guidance_tool(
218
- # how_to_find_request: str,
219
- # chat_session_obj: fastworkflow.ChatSession) -> str:
220
- # """
221
- # Request guidance on finding missing information.
222
- # The how_to_find_request must be plain text without any formatting.
223
- # """
224
- # class MissingInfoGuidanceSignature(dspy.Signature):
225
- # """
226
- # Carefully review the command info 'available_from' hints to see if the missing information can be found by executing a different command.
227
- # You may have to walk the graph of commands based on the 'available_from' hints to find the most appropriate command
228
- # Note that using the wrong command name can produce missing information errors. The requestor should double-check that the command name is correct.
229
- # """
230
- # command_info: str = dspy.InputField()
231
- # missing_information_guidance_request: str = dspy.InputField()
232
- # guidance: str = dspy.OutputField()
233
-
234
-
235
- # lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
236
- # with dspy.context(lm=lm):
237
- # guidance_func = dspy.ChainOfThought(MissingInfoGuidanceSignature)
238
- # prediction = guidance_func(
239
- # command_info=_what_can_i_do(chat_session_obj),
240
- # missing_information_guidance_request=how_to_find_request)
241
- # return prediction.guidance
242
-
243
194
  def _ask_user_tool(clarification_request: str, chat_session_obj: fastworkflow.ChatSession) -> str:
244
195
  """
245
196
  If the missing_information_guidance_tool does not help and only as the last resort, request clarification for missing information from the human user.
@@ -301,6 +252,13 @@ def initialize_workflow_tool_agent(chat_session: fastworkflow.ChatSession, max_i
301
252
  Commands must be formatted using plain text for command name followed by XML tags enclosing parameter values (if any) as follows: command_name <param1_name>param1_value</param1_name> <param2_name>param2_value</param2_name> ...
302
253
  Don't use this tool to respond to a clarification requests in PARAMETER EXTRACTION ERROR state
303
254
  """
255
+ # Check if this command originated from user input (iteration_counter == 0)
256
+ # Set flag in workflow context so validate_extracted_parameters can access it
257
+ is_user_command = chat_session_obj.workflow_tool_agent.iteration_counter <= 0
258
+ workflow = chat_session_obj.get_active_workflow()
259
+ if workflow:
260
+ workflow.context["is_user_command"] = is_user_command
261
+
304
262
  # Retry logic for workflow execution
305
263
  max_retries = 2
306
264
  for attempt in range(max_retries):
@@ -314,20 +272,17 @@ def initialize_workflow_tool_agent(chat_session: fastworkflow.ChatSession, max_i
314
272
  # Continue to next attempt
315
273
  logger.warning(f"Attempt {attempt + 1} failed for command '{command}': {str(e)}")
316
274
 
317
- # def missing_information_guidance(how_to_find_request: str) -> str:
318
- # """
319
- # Request guidance on finding missing information.
320
- # The how_to_find_request must be plain text without any formatting.
321
- # """
322
- # return _missing_information_guidance_tool(how_to_find_request, chat_session_obj=chat_session_obj)
323
-
324
275
  def ask_user(clarification_request: str) -> str:
325
276
  """
326
277
  Only as the last resort, request clarification for missing information from the human user.
327
278
  The clarification_request must be plain text without any formatting.
328
279
  Note that using the wrong command name can produce missing information errors. Double-check with the what_can_i_do tool to verify that the correct command name is being used
329
280
  """
330
- chat_session_obj.workflow_tool_agent.iteration_counter = 0 # reset iteration counter, everytime we ask the user
281
+ # reset iteration counter, everytime we ask the user
282
+ # reset to -1, because we are dual purposing (iteration_counter <= 0) to check
283
+ # if command passed to execute_workflow_query() originated either:
284
+ # externally or inside agent loop immediately after an ask_user()_call
285
+ chat_session_obj.workflow_tool_agent.iteration_counter = -1
331
286
  return _ask_user_tool(clarification_request, chat_session_obj=chat_session_obj)
332
287
 
333
288
  tools = [
@@ -400,9 +355,9 @@ def build_query_with_next_steps(user_query: str,
400
355
  return user_query
401
356
 
402
357
  steps_list = '\n'.join([f'{i + 1}. {task}' for i, task in enumerate(prediction.next_steps)])
403
- user_query_and_next_steps = f"{user_query}\n\nNext steps:\n{steps_list}"
358
+ user_query_and_next_steps = f"{user_query}\n\nExecute these next steps:\n{steps_list}"
404
359
  return (
405
- f'{available_commands}\n\nUser Query:\n{user_query_and_next_steps}'
360
+ f'User Query:\n{user_query_and_next_steps}'
406
361
  if with_agent_inputs_and_trajectory else
407
362
  user_query_and_next_steps
408
363
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastworkflow
3
- Version: 2.17.12
3
+ Version: 2.17.14
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
@@ -35,7 +35,7 @@ fastworkflow/build/navigator_stub_generator.py,sha256=_DSvHC6r1xWQiFHtUgPhI51nQf
35
35
  fastworkflow/build/pydantic_model_generator.py,sha256=oNyoANyUWBpHG-fE3tGL911RNvDzQXjxAm0ssvuXUH4,1854
36
36
  fastworkflow/build/utterance_generator.py,sha256=UrtkF0wyAZ1hiFitHX0g8w7Wh-D0leLCrP1aUACSfHo,299
37
37
  fastworkflow/cache_matching.py,sha256=OoB--1tO6-O4BKCuCrUbB0CkUr76J62K4VAf6MShi-w,7984
38
- fastworkflow/chat_session.py,sha256=O1HFst4GcglS0xR8lu2iaHiXzmNv0QVhdQ-8Nn2BFRw,35175
38
+ fastworkflow/chat_session.py,sha256=dvRH81Wmj0YCleZaCeWfx9zyqucYCOMJcldhvSLbFeY,35448
39
39
  fastworkflow/cli.py,sha256=n-PFDC0EOkq1zIK1Ip44at-VcaP9cW9aSxZ2IVj3VoE,23796
40
40
  fastworkflow/command_context_model.py,sha256=bQadDB_IH2lc0br46IT07Iej_j2KrAMderiVKqU7gno,15914
41
41
  fastworkflow/command_directory.py,sha256=aJ6UQCwevfF11KbcQB2Qz6mQ7Kj91pZtvHmQY6JFnao,29030
@@ -140,7 +140,7 @@ fastworkflow/examples/simple_workflow_template/application/__init__.py,sha256=47
140
140
  fastworkflow/examples/simple_workflow_template/application/workitem.py,sha256=Sm-QoX-EZvynkNf7uO3dViZF2VZqUlr6PAZZ7yjQEfk,40197
141
141
  fastworkflow/examples/simple_workflow_template/simple_workflow_template.json,sha256=A-dAl5iD9ehdMGGn05O2Kjwq6ZetqQjAGzlM1st0K9U,1237
142
142
  fastworkflow/examples/simple_workflow_template/startup_action.json,sha256=gj0-B4CqTYCs8OwHKhTu95H4uZbLsDf1th06IFfNXVs,75
143
- fastworkflow/intent_clarification_agent.py,sha256=UW5gj4Tg0wXduLRbDTkidVgBl-Cx-Esx_z9xRigMUJc,5215
143
+ fastworkflow/intent_clarification_agent.py,sha256=VYgpfx7EE0oToewwSaiCdz0VYSFq4Ql0UEsvyXUQhwM,5051
144
144
  fastworkflow/mcp_server.py,sha256=NxbLSKf2MA4lAHVcm6ZfiVuOjVO6IeV5Iw17wImFbxQ,8867
145
145
  fastworkflow/model_pipeline_training.py,sha256=P_9wrYSfJVSYCTu8VEPkgXJ16eH58LLCK4rCRbRFAVg,46740
146
146
  fastworkflow/refine/__main__.py,sha256=bDLpPNMcdp8U4EFnMdjxx1sPDQCZuEJoBURr2KebTng,3398
@@ -176,10 +176,10 @@ fastworkflow/utils/react.py,sha256=eROhiG0TQACLqa-4aVQB36kr4KsnqqQTQjqQdMpImCs,1
176
176
  fastworkflow/utils/signatures.py,sha256=uv1HxkVK8yzu6xt0ci8RUSgQW0Njaz22YuJVO_aNUEM,33393
177
177
  fastworkflow/utils/startup_progress.py,sha256=9icSdnpFAxzIq0sUliGpNaH0Efvrt5lDtGfURV5BD98,3539
178
178
  fastworkflow/workflow.py,sha256=37gn7e3ct-gdGw43zS6Ab_ADoJJBO4eJW2PywfUpjEg,18825
179
- fastworkflow/workflow_agent.py,sha256=z7AhYjRiebstyZ8_LvYmvC3kz8wNrmMipWt5InnwVNY,20763
179
+ fastworkflow/workflow_agent.py,sha256=UKjRTgnO9j7UNZVLPM8_N_g5anrPuJ6sJU8bWO_Z4EE,18434
180
180
  fastworkflow/workflow_inheritance_model.py,sha256=Pp-qSrQISgPfPjJVUfW84pc7HLmL2evuq0UVIYR51K0,7974
181
- fastworkflow-2.17.12.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
182
- fastworkflow-2.17.12.dist-info/METADATA,sha256=qWwoIZ4Aok4nOOMewR9cP-JdHw0FWjbPJIp-E54BMV0,30635
183
- fastworkflow-2.17.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
184
- fastworkflow-2.17.12.dist-info/entry_points.txt,sha256=m8HqoPzCyaZLAx-V5X8MJgw3Lx3GiPDlxNEZ7K-Gb-U,54
185
- fastworkflow-2.17.12.dist-info/RECORD,,
181
+ fastworkflow-2.17.14.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
182
+ fastworkflow-2.17.14.dist-info/METADATA,sha256=K_v08Sjjy4Jo3kfFVA6WYBQ0udXtTcgC5FnXex7WZa0,30635
183
+ fastworkflow-2.17.14.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
184
+ fastworkflow-2.17.14.dist-info/entry_points.txt,sha256=m8HqoPzCyaZLAx-V5X8MJgw3Lx3GiPDlxNEZ7K-Gb-U,54
185
+ fastworkflow-2.17.14.dist-info/RECORD,,