fastworkflow 2.15.5__py3-none-any.whl → 2.17.13__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.
- fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py +1 -1
- fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py +16 -2
- fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py +27 -570
- fastworkflow/_workflows/command_metadata_extraction/intent_detection.py +360 -0
- fastworkflow/_workflows/command_metadata_extraction/parameter_extraction.py +411 -0
- fastworkflow/chat_session.py +379 -206
- fastworkflow/cli.py +80 -165
- fastworkflow/command_context_model.py +73 -7
- fastworkflow/command_executor.py +14 -5
- fastworkflow/command_metadata_api.py +106 -6
- fastworkflow/examples/fastworkflow.env +2 -1
- fastworkflow/examples/fastworkflow.passwords.env +2 -1
- fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py +32 -3
- fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py +6 -5
- fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py +32 -3
- fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py +13 -2
- fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py +1 -1
- fastworkflow/intent_clarification_agent.py +131 -0
- fastworkflow/mcp_server.py +3 -3
- fastworkflow/run/__main__.py +33 -40
- fastworkflow/run_fastapi_mcp/README.md +373 -0
- fastworkflow/run_fastapi_mcp/__main__.py +1300 -0
- fastworkflow/run_fastapi_mcp/conversation_store.py +391 -0
- fastworkflow/run_fastapi_mcp/jwt_manager.py +341 -0
- fastworkflow/run_fastapi_mcp/mcp_specific.py +103 -0
- fastworkflow/run_fastapi_mcp/redoc_2_standalone_html.py +40 -0
- fastworkflow/run_fastapi_mcp/utils.py +517 -0
- fastworkflow/train/__main__.py +1 -1
- fastworkflow/utils/chat_adapter.py +99 -0
- fastworkflow/utils/python_utils.py +4 -4
- fastworkflow/utils/react.py +258 -0
- fastworkflow/utils/signatures.py +338 -139
- fastworkflow/workflow.py +1 -5
- fastworkflow/workflow_agent.py +185 -133
- {fastworkflow-2.15.5.dist-info → fastworkflow-2.17.13.dist-info}/METADATA +16 -18
- {fastworkflow-2.15.5.dist-info → fastworkflow-2.17.13.dist-info}/RECORD +40 -30
- fastworkflow/run_agent/__main__.py +0 -294
- fastworkflow/run_agent/agent_module.py +0 -194
- /fastworkflow/{run_agent → run_fastapi_mcp}/__init__.py +0 -0
- {fastworkflow-2.15.5.dist-info → fastworkflow-2.17.13.dist-info}/LICENSE +0 -0
- {fastworkflow-2.15.5.dist-info → fastworkflow-2.17.13.dist-info}/WHEEL +0 -0
- {fastworkflow-2.15.5.dist-info → fastworkflow-2.17.13.dist-info}/entry_points.txt +0 -0
|
@@ -4,14 +4,16 @@ fastworkflow/_commands/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
4
4
|
fastworkflow/_workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
fastworkflow/_workflows/command_metadata_extraction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/abort.py,sha256=C5H_sOOC1KBaW888QarWnWffMoV7VnZ03q4GMqmitSE,1388
|
|
7
|
-
fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py,sha256=
|
|
7
|
+
fastworkflow/_workflows/command_metadata_extraction/_commands/ErrorCorrection/you_misunderstood.py,sha256=VHfhwlqc1ceG9P_wL8Fl7dpJA2UlcSrcXhz7zZU9NpA,2517
|
|
8
8
|
fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/go_up.py,sha256=K526OAf5ks95SwqVdRNVxLM_AWDfA1qXbkNYq0dANwg,1889
|
|
9
9
|
fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/reset_context.py,sha256=xvInu6uDw0YRUHVXNyTZphSr75f8QiQgFwDtv7SlE9o,1346
|
|
10
|
-
fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py,sha256=
|
|
10
|
+
fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_can_i_do.py,sha256=KEYZ8qJG9j_93ycy2CbRdvoqJZ5FawmwjDyRlXWMNeM,6887
|
|
11
11
|
fastworkflow/_workflows/command_metadata_extraction/_commands/IntentDetection/what_is_current_context.py,sha256=S5RQLr62Q2MnKU85nw4IW_ueAK_FXvhcY9gXajFxujg,1464
|
|
12
12
|
fastworkflow/_workflows/command_metadata_extraction/_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py,sha256=
|
|
13
|
+
fastworkflow/_workflows/command_metadata_extraction/_commands/wildcard.py,sha256=Sqpc2hwM-DgmsqiHu3OoOuqo3XnHLkFlmyYCJA8nj_8,7843
|
|
14
14
|
fastworkflow/_workflows/command_metadata_extraction/command_context_model.json,sha256=zGWBweQSmFf7WsfR_F2DE7AJ8S8-q7F9ZbvyccysJJI,117
|
|
15
|
+
fastworkflow/_workflows/command_metadata_extraction/intent_detection.py,sha256=Ci0Cut_rH8wpUlLEsTMK-OhT3AO2nKgJmXQYIsoTzJw,14543
|
|
16
|
+
fastworkflow/_workflows/command_metadata_extraction/parameter_extraction.py,sha256=vF9d6cUIotULTYoVCg3DdNnoJ6pn7A7LEKufgnR98no,17522
|
|
15
17
|
fastworkflow/build/__main__.py,sha256=NtedkZfM56qoEJ5vQECSURbE8AMTfwHN3tAZyZoWabk,15905
|
|
16
18
|
fastworkflow/build/ast_class_extractor.py,sha256=F9OG4stkp7w3kadKqxMm8h3ZDSp_zg6mwcrKMl_XqdI,13527
|
|
17
19
|
fastworkflow/build/class_analysis_structures.py,sha256=UWOKcs9pCiNuXc64hNywkTJq5X5KfG1pqdSZwWiZh-c,4053
|
|
@@ -33,13 +35,13 @@ fastworkflow/build/navigator_stub_generator.py,sha256=_DSvHC6r1xWQiFHtUgPhI51nQf
|
|
|
33
35
|
fastworkflow/build/pydantic_model_generator.py,sha256=oNyoANyUWBpHG-fE3tGL911RNvDzQXjxAm0ssvuXUH4,1854
|
|
34
36
|
fastworkflow/build/utterance_generator.py,sha256=UrtkF0wyAZ1hiFitHX0g8w7Wh-D0leLCrP1aUACSfHo,299
|
|
35
37
|
fastworkflow/cache_matching.py,sha256=OoB--1tO6-O4BKCuCrUbB0CkUr76J62K4VAf6MShi-w,7984
|
|
36
|
-
fastworkflow/chat_session.py,sha256=
|
|
37
|
-
fastworkflow/cli.py,sha256=
|
|
38
|
-
fastworkflow/command_context_model.py,sha256=
|
|
38
|
+
fastworkflow/chat_session.py,sha256=O1HFst4GcglS0xR8lu2iaHiXzmNv0QVhdQ-8Nn2BFRw,35175
|
|
39
|
+
fastworkflow/cli.py,sha256=n-PFDC0EOkq1zIK1Ip44at-VcaP9cW9aSxZ2IVj3VoE,23796
|
|
40
|
+
fastworkflow/command_context_model.py,sha256=bQadDB_IH2lc0br46IT07Iej_j2KrAMderiVKqU7gno,15914
|
|
39
41
|
fastworkflow/command_directory.py,sha256=aJ6UQCwevfF11KbcQB2Qz6mQ7Kj91pZtvHmQY6JFnao,29030
|
|
40
|
-
fastworkflow/command_executor.py,sha256=
|
|
42
|
+
fastworkflow/command_executor.py,sha256=WTSrukv6UDQfWUDSNleIQ1TxwDnAQIKIimh4sQVwnig,8457
|
|
41
43
|
fastworkflow/command_interfaces.py,sha256=PWIKlcp0G8nmYl0vkrg1o6QzJL0pxXkfrn1joqTa0eU,460
|
|
42
|
-
fastworkflow/command_metadata_api.py,sha256=
|
|
44
|
+
fastworkflow/command_metadata_api.py,sha256=PBu9c8iwYLcRy7YipAv6wKDimK7YZOweTe_q3rFuDMg,44191
|
|
43
45
|
fastworkflow/command_routing.py,sha256=R7194pcY0d2VHzmCu9ALacm1UvNuIRIvTn8mLp-EZIM,17219
|
|
44
46
|
fastworkflow/docs/context_modules_prd.txt,sha256=9wvs3LgNoIVXAczo1sXBIV4YmFqVhzC2ja1T3K7FG04,2199
|
|
45
47
|
fastworkflow/examples/extended_workflow_example/README.md,sha256=2O0O4Bg--fwF98YDScnkNCUL3PcH8KpX2p6I1cwNWeg,2864
|
|
@@ -48,8 +50,8 @@ fastworkflow/examples/extended_workflow_example/_commands/generate_report.py,sha
|
|
|
48
50
|
fastworkflow/examples/extended_workflow_example/_commands/startup.py,sha256=V5Q29148SvXw6i3i0pKTuNWsv2xnkUMsHHuzt1ndxro,1028
|
|
49
51
|
fastworkflow/examples/extended_workflow_example/simple_workflow_template.json,sha256=A-dAl5iD9ehdMGGn05O2Kjwq6ZetqQjAGzlM1st0K9U,1237
|
|
50
52
|
fastworkflow/examples/extended_workflow_example/workflow_inheritance_model.json,sha256=TBk272pqfyRKzm4T-I6_nGfbcdmEzjwon7kFPWtgyhw,81
|
|
51
|
-
fastworkflow/examples/fastworkflow.env,sha256=
|
|
52
|
-
fastworkflow/examples/fastworkflow.passwords.env,sha256=
|
|
53
|
+
fastworkflow/examples/fastworkflow.env,sha256=mLI1fWqkzjcp9uzfHw81mlOx4JFb8Ch_TBy8dX1Dsok,675
|
|
54
|
+
fastworkflow/examples/fastworkflow.passwords.env,sha256=9bI62EokFWT_YPcO0UAvO1ZTG2wM76Jbe5cKE7_KTRg,517
|
|
53
55
|
fastworkflow/examples/hello_world/_commands/README.md,sha256=pYOTGqVx41ZIuNc6hPTEJzNcMQ2Vwx3PN74ifSlayvU,1297
|
|
54
56
|
fastworkflow/examples/hello_world/_commands/add_two_numbers.py,sha256=0lFGK1llT6u6fByvzCDPdegjY6gWcerM2cvxVSo7lIw,2232
|
|
55
57
|
fastworkflow/examples/hello_world/_commands/context_inheritance_model.json,sha256=RBNvo1WzZ4oRRq0W9-hknpT7T8If536DEMBg9hyq_4o,2
|
|
@@ -84,19 +86,19 @@ fastworkflow/examples/messaging_app_4/context_hierarchy_model.json,sha256=p1PkLF
|
|
|
84
86
|
fastworkflow/examples/messaging_app_4/startup_action.json,sha256=HhS0ApuK1wZmX2M0pVusCkgrV0IU7BwvkfEOpRfN95A,84
|
|
85
87
|
fastworkflow/examples/retail_workflow/_commands/calculate.py,sha256=uj-Yg0RSiSPkK7Y0AZN1fgDdL0GWIw33g9ARAPGFFVU,2285
|
|
86
88
|
fastworkflow/examples/retail_workflow/_commands/cancel_pending_order.py,sha256=npU7sERB915WJyqjuku6L63sxvXtrWGkjoTrU0nNhEU,4466
|
|
87
|
-
fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py,sha256=
|
|
88
|
-
fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py,sha256=
|
|
89
|
+
fastworkflow/examples/retail_workflow/_commands/exchange_delivered_order_items.py,sha256=6g04D3eHUQdIBu3wqPbhHMjJUK_91uHxaZrlDggnFS0,5349
|
|
90
|
+
fastworkflow/examples/retail_workflow/_commands/find_user_id_by_email.py,sha256=EUGj_YJCIceebQghrlC3uDdJsxsAg2hxS3jFcaN3mX8,2761
|
|
89
91
|
fastworkflow/examples/retail_workflow/_commands/find_user_id_by_name_zip.py,sha256=lA9UfEkBNjCXozM4fALSZZuS0DgO3W1qQ2cg0dv1XUA,3340
|
|
90
92
|
fastworkflow/examples/retail_workflow/_commands/get_order_details.py,sha256=X5tcMfx0lBm5vot7Ssn8Uzg0UaTPJU7GTn0C8fGnGxM,3584
|
|
91
93
|
fastworkflow/examples/retail_workflow/_commands/get_product_details.py,sha256=Qfzaz3hHNia9GJvR9Lhdv8qJWdy-GZ6VbzTCYyD4Hh8,2842
|
|
92
94
|
fastworkflow/examples/retail_workflow/_commands/get_user_details.py,sha256=zk_QYvoj-DYP4muq0p9uDF_puCKPwy9OZrYhyM6grnI,3091
|
|
93
95
|
fastworkflow/examples/retail_workflow/_commands/list_all_product_types.py,sha256=qnxbHU6PwWiV0E9jO6jYOIs1w5RCrTYQYqYyip14VzI,2529
|
|
94
96
|
fastworkflow/examples/retail_workflow/_commands/modify_pending_order_address.py,sha256=As6TZ2uPicrylJCULN53maHTUj4Sq-XN4C2sF653EDk,3826
|
|
95
|
-
fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py,sha256=
|
|
97
|
+
fastworkflow/examples/retail_workflow/_commands/modify_pending_order_items.py,sha256=t4UbYlgAADyzrE37PDcjZPd7UVqqlYE906d07zdMbKs,5346
|
|
96
98
|
fastworkflow/examples/retail_workflow/_commands/modify_pending_order_payment.py,sha256=zw8mhNkT6HoSPk2ADVROyGIIPpXsT3BhB5YrRnkCtmQ,3356
|
|
97
99
|
fastworkflow/examples/retail_workflow/_commands/modify_user_address.py,sha256=2Zxgbge6wDufWEvk5D7PgOkYb3bayXGH_d0Kr0AFRsw,3864
|
|
98
|
-
fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py,sha256=
|
|
99
|
-
fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py,sha256=
|
|
100
|
+
fastworkflow/examples/retail_workflow/_commands/return_delivered_order_items.py,sha256=xMKn1pO91BAjYURo5lf2GjpoOm1iQxsxidq69svVRQk,4222
|
|
101
|
+
fastworkflow/examples/retail_workflow/_commands/transfer_to_human_agents.py,sha256=09YXFSeeTN2-bNh_CzHyUN-XhYAbXOe403tjP2zo3KI,2924
|
|
100
102
|
fastworkflow/examples/retail_workflow/context_inheritance_model.json,sha256=jrlby8FUUwkx4V_EGMix_pkQlWcUCVUgmeoapZaZnt4,3
|
|
101
103
|
fastworkflow/examples/retail_workflow/retail_data/__init__.py,sha256=HW8jqarRRTRtNBMp8jqQBTanFTQQC_uShqY_PiGrVtI,629
|
|
102
104
|
fastworkflow/examples/retail_workflow/retail_data/orders.json,sha256=JZihJYbSjy1r0WvIb0yAACm2rxjgq7XEde9chpwRztE,1810945
|
|
@@ -138,19 +140,26 @@ fastworkflow/examples/simple_workflow_template/application/__init__.py,sha256=47
|
|
|
138
140
|
fastworkflow/examples/simple_workflow_template/application/workitem.py,sha256=Sm-QoX-EZvynkNf7uO3dViZF2VZqUlr6PAZZ7yjQEfk,40197
|
|
139
141
|
fastworkflow/examples/simple_workflow_template/simple_workflow_template.json,sha256=A-dAl5iD9ehdMGGn05O2Kjwq6ZetqQjAGzlM1st0K9U,1237
|
|
140
142
|
fastworkflow/examples/simple_workflow_template/startup_action.json,sha256=gj0-B4CqTYCs8OwHKhTu95H4uZbLsDf1th06IFfNXVs,75
|
|
141
|
-
fastworkflow/
|
|
143
|
+
fastworkflow/intent_clarification_agent.py,sha256=VYgpfx7EE0oToewwSaiCdz0VYSFq4Ql0UEsvyXUQhwM,5051
|
|
144
|
+
fastworkflow/mcp_server.py,sha256=NxbLSKf2MA4lAHVcm6ZfiVuOjVO6IeV5Iw17wImFbxQ,8867
|
|
142
145
|
fastworkflow/model_pipeline_training.py,sha256=P_9wrYSfJVSYCTu8VEPkgXJ16eH58LLCK4rCRbRFAVg,46740
|
|
143
146
|
fastworkflow/refine/__main__.py,sha256=bDLpPNMcdp8U4EFnMdjxx1sPDQCZuEJoBURr2KebTng,3398
|
|
144
147
|
fastworkflow/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
145
|
-
fastworkflow/run/__main__.py,sha256=
|
|
146
|
-
fastworkflow/
|
|
147
|
-
fastworkflow/
|
|
148
|
-
fastworkflow/
|
|
148
|
+
fastworkflow/run/__main__.py,sha256=XmybAsr1MnCx8tzvhWxtBT7xu2Om3PVZFtABXavPccU,12075
|
|
149
|
+
fastworkflow/run_fastapi_mcp/README.md,sha256=dAmG2KF-9mqSjyIPSA9vhUit-DjsDH6WJUDCkQ3C1is,11943
|
|
150
|
+
fastworkflow/run_fastapi_mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
151
|
+
fastworkflow/run_fastapi_mcp/__main__.py,sha256=R3A5PUoBXtEufaTTKF92kWhBuDg3xsVG0IQEyg4XJOI,53536
|
|
152
|
+
fastworkflow/run_fastapi_mcp/conversation_store.py,sha256=2qnNLO_RVHznbIzTjpdff7szsrGyr1FVt1spcKvkrKk,13534
|
|
153
|
+
fastworkflow/run_fastapi_mcp/jwt_manager.py,sha256=o3JLV71WiKNhr61KFIrYDnYQvvNYrqhSqEnsWNBUya4,12480
|
|
154
|
+
fastworkflow/run_fastapi_mcp/mcp_specific.py,sha256=RdOPcPn68KlxNSM9Vb2yeYEDNGoNTcKZq-AC0cd86cw,4506
|
|
155
|
+
fastworkflow/run_fastapi_mcp/redoc_2_standalone_html.py,sha256=oYWn30O-xKX6pVjunCeLupyOM2DbeZ3QgFj-F2LalOE,1191
|
|
156
|
+
fastworkflow/run_fastapi_mcp/utils.py,sha256=SX6meWba0T-iYn7YmEajbwJrijfVVUuYGv4usDXzA2c,19589
|
|
149
157
|
fastworkflow/train/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
150
|
-
fastworkflow/train/__main__.py,sha256=
|
|
158
|
+
fastworkflow/train/__main__.py,sha256=03OeHVwa7MmBNHGtBrQ-0cT2rtrVtAiQtvQBzkcbp3w,8533
|
|
151
159
|
fastworkflow/train/generate_synthetic.py,sha256=sTDk-E5ewkS4o-0LJeofiEv4uXGpqdGcFRYKY_Yf36Y,5322
|
|
152
160
|
fastworkflow/user_message_queues.py,sha256=svbuFxQ16q6Tz6urPWfD4IEsOTMxtS1Kc1PP8EE8AWg,1422
|
|
153
161
|
fastworkflow/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
162
|
+
fastworkflow/utils/chat_adapter.py,sha256=-U5JFiPynDhSYXJ75wdY0EA-hH8QPaq1bzA6ju4ZnVc,4090
|
|
154
163
|
fastworkflow/utils/command_dependency_graph.py,sha256=7YmAnVXcaLsPVeC3SvM4pGdUsCUxWM4H2qXrtGwQpAI,13512
|
|
155
164
|
fastworkflow/utils/context_utils.py,sha256=mjYVzNJCmimNMmBdOKfzFeDSws_oAADAwcfz_N6sR7M,749
|
|
156
165
|
fastworkflow/utils/dspy_cache_utils.py,sha256=OP2IsWPMGCdhjC-4iRqggWgTEfvPxFN_78tV1_C6uHY,3725
|
|
@@ -162,14 +171,15 @@ fastworkflow/utils/generate_param_examples.py,sha256=K0x1Zwe82xqhKA15AYTodWg7mqu
|
|
|
162
171
|
fastworkflow/utils/logging.py,sha256=2SA-04fg7Lx_vGf980tfCOGDQxBvU9X6Vbhv47rbdaw,4110
|
|
163
172
|
fastworkflow/utils/parameterize_func_decorator.py,sha256=V6YJnishWRCdwiBQW6P17hmGGrga0Empk-AN5Gm7iMk,633
|
|
164
173
|
fastworkflow/utils/pydantic_model_2_dspy_signature_class.py,sha256=w1pvl8rJq48ulFwaAtBgfXYn_SBIDBgq1aLMUg1zJn8,12875
|
|
165
|
-
fastworkflow/utils/python_utils.py,sha256=
|
|
166
|
-
fastworkflow/utils/
|
|
174
|
+
fastworkflow/utils/python_utils.py,sha256=D0JBdzkwKoyK7XvZcnIxOgsS8CRGdvuW-zcO45_pfOA,8252
|
|
175
|
+
fastworkflow/utils/react.py,sha256=eROhiG0TQACLqa-4aVQB36kr4KsnqqQTQjqQdMpImCs,12384
|
|
176
|
+
fastworkflow/utils/signatures.py,sha256=uv1HxkVK8yzu6xt0ci8RUSgQW0Njaz22YuJVO_aNUEM,33393
|
|
167
177
|
fastworkflow/utils/startup_progress.py,sha256=9icSdnpFAxzIq0sUliGpNaH0Efvrt5lDtGfURV5BD98,3539
|
|
168
|
-
fastworkflow/workflow.py,sha256=
|
|
169
|
-
fastworkflow/workflow_agent.py,sha256=
|
|
178
|
+
fastworkflow/workflow.py,sha256=37gn7e3ct-gdGw43zS6Ab_ADoJJBO4eJW2PywfUpjEg,18825
|
|
179
|
+
fastworkflow/workflow_agent.py,sha256=UKjRTgnO9j7UNZVLPM8_N_g5anrPuJ6sJU8bWO_Z4EE,18434
|
|
170
180
|
fastworkflow/workflow_inheritance_model.py,sha256=Pp-qSrQISgPfPjJVUfW84pc7HLmL2evuq0UVIYR51K0,7974
|
|
171
|
-
fastworkflow-2.
|
|
172
|
-
fastworkflow-2.
|
|
173
|
-
fastworkflow-2.
|
|
174
|
-
fastworkflow-2.
|
|
175
|
-
fastworkflow-2.
|
|
181
|
+
fastworkflow-2.17.13.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
182
|
+
fastworkflow-2.17.13.dist-info/METADATA,sha256=f2_sS01eLGGCtXtYI39KI6Q4E2pfzAaWPOOYZqc0sAQ,30635
|
|
183
|
+
fastworkflow-2.17.13.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
184
|
+
fastworkflow-2.17.13.dist-info/entry_points.txt,sha256=m8HqoPzCyaZLAx-V5X8MJgw3Lx3GiPDlxNEZ7K-Gb-U,54
|
|
185
|
+
fastworkflow-2.17.13.dist-info/RECORD,,
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import contextlib
|
|
3
|
-
import json
|
|
4
|
-
import os
|
|
5
|
-
import queue
|
|
6
|
-
import time
|
|
7
|
-
import threading
|
|
8
|
-
from typing import Optional
|
|
9
|
-
from dotenv import dotenv_values
|
|
10
|
-
from queue import Empty
|
|
11
|
-
|
|
12
|
-
import dspy
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# Instantiate a global console for consistent styling
|
|
16
|
-
console = None
|
|
17
|
-
|
|
18
|
-
def check_workflow_trained(workflow_path: str) -> bool:
|
|
19
|
-
"""
|
|
20
|
-
Check if a workflow has been trained by looking for the tiny_ambiguous_threshold.json file
|
|
21
|
-
in the ___command_info/global folder.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
workflow_path: Path to the workflow folder
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
bool: True if the workflow appears to be trained, False otherwise
|
|
28
|
-
"""
|
|
29
|
-
# Path to the global command info directory
|
|
30
|
-
global_cmd_info_path = os.path.join(workflow_path, "___command_info", "global")
|
|
31
|
-
|
|
32
|
-
# Path to the tiny_ambiguous_threshold.json file
|
|
33
|
-
threshold_file_path = os.path.join(global_cmd_info_path, "tiny_ambiguous_threshold.json")
|
|
34
|
-
|
|
35
|
-
# Check if the file exists
|
|
36
|
-
return os.path.exists(threshold_file_path)
|
|
37
|
-
|
|
38
|
-
def main():
|
|
39
|
-
# Third-party CLI prettification libraries
|
|
40
|
-
from rich.console import Console
|
|
41
|
-
from rich.panel import Panel
|
|
42
|
-
from rich.table import Table
|
|
43
|
-
from rich.text import Text
|
|
44
|
-
from rich.console import Group
|
|
45
|
-
from prompt_toolkit import PromptSession
|
|
46
|
-
from prompt_toolkit.patch_stdout import patch_stdout
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
import fastworkflow
|
|
50
|
-
from fastworkflow.utils import dspy_utils
|
|
51
|
-
from fastworkflow.command_executor import CommandExecutor
|
|
52
|
-
from .agent_module import initialize_dspy_agent
|
|
53
|
-
|
|
54
|
-
# Progress bar helper
|
|
55
|
-
from fastworkflow.utils.startup_progress import StartupProgress
|
|
56
|
-
|
|
57
|
-
# Instantiate a global console for consistent styling
|
|
58
|
-
global console
|
|
59
|
-
console = Console()
|
|
60
|
-
prompt_session = PromptSession("User > ")
|
|
61
|
-
|
|
62
|
-
def _build_artifact_table(artifacts: dict[str, str]) -> Table:
|
|
63
|
-
"""Return a rich.Table representation for artifact key-value pairs."""
|
|
64
|
-
table = Table(show_header=True, header_style="bold cyan", box=None)
|
|
65
|
-
table.add_column("Name", style="cyan", overflow="fold")
|
|
66
|
-
table.add_column("Value", style="white", overflow="fold")
|
|
67
|
-
for name, value in artifacts.items():
|
|
68
|
-
table.add_row(str(name), str(value))
|
|
69
|
-
return table
|
|
70
|
-
|
|
71
|
-
def print_command_output(command_output):
|
|
72
|
-
"""Pretty-print workflow output using rich panels and tables."""
|
|
73
|
-
for command_response in command_output.command_responses:
|
|
74
|
-
workflow_id = "UnknownSession"
|
|
75
|
-
with contextlib.suppress(Exception):
|
|
76
|
-
workflow = fastworkflow.ChatSession.get_active_workflow()
|
|
77
|
-
workflow_id = workflow.id if workflow else "UnknownSession"
|
|
78
|
-
|
|
79
|
-
# Collect body elements for the panel content
|
|
80
|
-
body_renderables = []
|
|
81
|
-
|
|
82
|
-
if command_response.response:
|
|
83
|
-
body_renderables.append(Text(command_response.response, style="green"))
|
|
84
|
-
|
|
85
|
-
if command_response.artifacts:
|
|
86
|
-
body_renderables.extend(
|
|
87
|
-
(
|
|
88
|
-
Text("Artifacts", style="bold cyan"),
|
|
89
|
-
_build_artifact_table(command_response.artifacts),
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
if command_response.next_actions:
|
|
93
|
-
actions_table = Table(show_header=False, box=None)
|
|
94
|
-
for act in command_response.next_actions:
|
|
95
|
-
actions_table.add_row(Text(str(act), style="blue"))
|
|
96
|
-
body_renderables.extend(
|
|
97
|
-
(Text("Next Actions", style="bold blue"), actions_table)
|
|
98
|
-
)
|
|
99
|
-
if command_response.recommendations:
|
|
100
|
-
rec_table = Table(show_header=False, box=None)
|
|
101
|
-
for rec in command_response.recommendations:
|
|
102
|
-
rec_table.add_row(Text(str(rec), style="magenta"))
|
|
103
|
-
body_renderables.extend(
|
|
104
|
-
(Text("Recommendations", style="bold magenta"), rec_table)
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
panel_title = f"[bold yellow]Workflow {workflow_id}[/bold yellow]"
|
|
108
|
-
# Group all renderables together
|
|
109
|
-
group = Group(*body_renderables)
|
|
110
|
-
# Use the group in the panel
|
|
111
|
-
panel = Panel.fit(group, title=panel_title, border_style="green")
|
|
112
|
-
console.print(panel)
|
|
113
|
-
|
|
114
|
-
parser = argparse.ArgumentParser(description="AI Assistant for workflow processing")
|
|
115
|
-
parser.add_argument("workflow_path", help="Path to the workflow folder")
|
|
116
|
-
parser.add_argument("env_file_path", help="Path to the environment file")
|
|
117
|
-
parser.add_argument("passwords_file_path", help="Path to the passwords file")
|
|
118
|
-
parser.add_argument(
|
|
119
|
-
"--context_file_path", help="Optional context file path", default=""
|
|
120
|
-
)
|
|
121
|
-
parser.add_argument(
|
|
122
|
-
"--startup_command", help="Optional startup command", default=""
|
|
123
|
-
)
|
|
124
|
-
parser.add_argument(
|
|
125
|
-
"--startup_action", help="Optional startup action", default=""
|
|
126
|
-
)
|
|
127
|
-
parser.add_argument(
|
|
128
|
-
"--keep_alive", help="Optional keep_alive", default=True
|
|
129
|
-
)
|
|
130
|
-
parser.add_argument(
|
|
131
|
-
"--project_folderpath", help="Optional path to project folder containing application code", default=None
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
args = parser.parse_args()
|
|
135
|
-
|
|
136
|
-
if not os.path.isdir(args.workflow_path):
|
|
137
|
-
console.print(f"[bold red]Error:[/bold red] The specified workflow path '{args.workflow_path}' is not a valid directory.")
|
|
138
|
-
exit(1)
|
|
139
|
-
|
|
140
|
-
console.print(Panel(f"Running fastWorkflow: [bold]{args.workflow_path}[/bold]", title="[bold green]fastworkflow[/bold green]", border_style="green"))
|
|
141
|
-
console.print("[bold green]Tip:[/bold green] Type 'exit' to quit the application.")
|
|
142
|
-
|
|
143
|
-
# ------------------------------------------------------------------
|
|
144
|
-
# Startup progress bar ------------------------------------------------
|
|
145
|
-
# ------------------------------------------------------------------
|
|
146
|
-
command_info_root = os.path.join(args.workflow_path, "___command_info")
|
|
147
|
-
subdir_count = 0
|
|
148
|
-
if os.path.isdir(command_info_root):
|
|
149
|
-
subdir_count = len([d for d in os.listdir(command_info_root) if os.path.isdir(os.path.join(command_info_root, d))])
|
|
150
|
-
|
|
151
|
-
StartupProgress.begin(total=3)
|
|
152
|
-
|
|
153
|
-
StartupProgress.advance("Imported fastworkflow modules")
|
|
154
|
-
|
|
155
|
-
env_vars = {
|
|
156
|
-
**dotenv_values(args.env_file_path),
|
|
157
|
-
**dotenv_values(args.passwords_file_path)
|
|
158
|
-
}
|
|
159
|
-
StartupProgress.advance("fastworkflow.init complete")
|
|
160
|
-
|
|
161
|
-
fastworkflow.init(env_vars=env_vars)
|
|
162
|
-
|
|
163
|
-
LLM_AGENT = fastworkflow.get_env_var("LLM_AGENT")
|
|
164
|
-
if not LLM_AGENT:
|
|
165
|
-
console.print("[bold red]Error:[/bold red] DSPy Language Model not provided. Set LLM_AGENT environment variable.")
|
|
166
|
-
exit(1)
|
|
167
|
-
|
|
168
|
-
# Check if the workflow has been trained
|
|
169
|
-
if not check_workflow_trained(args.workflow_path):
|
|
170
|
-
# Extract workflow name for the error message
|
|
171
|
-
workflow_name = os.path.basename(args.workflow_path)
|
|
172
|
-
console.print(Panel(
|
|
173
|
-
f"To train this workflow, run:\n"
|
|
174
|
-
f"[bold white]fastworkflow train {args.workflow_path}[/bold white]",
|
|
175
|
-
title="[bold red]Workflow '{workflow_name}' has not been trained[/bold red]",
|
|
176
|
-
border_style="red"
|
|
177
|
-
))
|
|
178
|
-
exit(1)
|
|
179
|
-
|
|
180
|
-
# this could be None
|
|
181
|
-
lm = dspy_utils.get_lm("LLM_AGENT", "LITELLM_API_KEY_AGENT")
|
|
182
|
-
|
|
183
|
-
startup_action: Optional[fastworkflow.Action] = None
|
|
184
|
-
if args.startup_action:
|
|
185
|
-
with open(args.startup_action, 'r') as file:
|
|
186
|
-
startup_action_dict = json.load(file)
|
|
187
|
-
startup_action = fastworkflow.Action(**startup_action_dict)
|
|
188
|
-
|
|
189
|
-
context_dict = None
|
|
190
|
-
if args.context_file_path:
|
|
191
|
-
with open(args.context_file_path, 'r') as file:
|
|
192
|
-
context_dict = json.load(file)
|
|
193
|
-
|
|
194
|
-
# Create the chat session in agent mode
|
|
195
|
-
fastworkflow.chat_session = fastworkflow.ChatSession(run_as_agent=True)
|
|
196
|
-
|
|
197
|
-
# Start the workflow within the chat session
|
|
198
|
-
fastworkflow.chat_session.start_workflow(
|
|
199
|
-
args.workflow_path,
|
|
200
|
-
workflow_context=context_dict,
|
|
201
|
-
startup_command=args.startup_command,
|
|
202
|
-
startup_action=startup_action,
|
|
203
|
-
keep_alive=args.keep_alive,
|
|
204
|
-
project_folderpath=args.project_folderpath
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
StartupProgress.advance("ChatSession ready")
|
|
208
|
-
StartupProgress.end()
|
|
209
|
-
|
|
210
|
-
try:
|
|
211
|
-
react_agent = initialize_dspy_agent(fastworkflow.chat_session)
|
|
212
|
-
except (EnvironmentError, RuntimeError) as e:
|
|
213
|
-
console.print(f"[bold red]Failed to initialize DSPy agent:[/bold red] {e}")
|
|
214
|
-
exit(1)
|
|
215
|
-
|
|
216
|
-
with contextlib.suppress(queue.Empty):
|
|
217
|
-
if command_output := fastworkflow.chat_session.command_output_queue.get(
|
|
218
|
-
timeout=0.1
|
|
219
|
-
):
|
|
220
|
-
console.print(Panel("Startup Command Output", border_style="dim"))
|
|
221
|
-
print_command_output(command_output)
|
|
222
|
-
console.print(Panel("End Startup Command Output", border_style="dim"))
|
|
223
|
-
|
|
224
|
-
while True:
|
|
225
|
-
if not args.keep_alive and fastworkflow.chat_session.workflow_is_complete:
|
|
226
|
-
console.print("[blue]Workflow complete and keep_alive is false. Exiting...[/blue]")
|
|
227
|
-
break
|
|
228
|
-
|
|
229
|
-
with patch_stdout():
|
|
230
|
-
user_input_str = prompt_session.prompt()
|
|
231
|
-
if user_input_str.lower() == "exit":
|
|
232
|
-
console.print("[blue]User requested exit. Exiting...[/blue]")
|
|
233
|
-
break
|
|
234
|
-
|
|
235
|
-
try:
|
|
236
|
-
# Use a thread-safe way to store the agent response
|
|
237
|
-
agent_response_container = {"response": None, "error": None}
|
|
238
|
-
|
|
239
|
-
# Function to run agent processing in a separate thread
|
|
240
|
-
def process_agent_query():
|
|
241
|
-
try:
|
|
242
|
-
with dspy.context(lm=lm):
|
|
243
|
-
agent_response_container["response"] = react_agent(user_query=user_input_str)
|
|
244
|
-
except Exception as e:
|
|
245
|
-
agent_response_container["error"] = e
|
|
246
|
-
|
|
247
|
-
# Start processing thread
|
|
248
|
-
agent_thread = threading.Thread(target=process_agent_query)
|
|
249
|
-
agent_thread.daemon = True
|
|
250
|
-
agent_thread.start()
|
|
251
|
-
|
|
252
|
-
# Queues used by the agent to request user clarification
|
|
253
|
-
from fastworkflow.run_agent.agent_module import (
|
|
254
|
-
clarification_request_queue,
|
|
255
|
-
clarification_response_queue,
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
with console.status("[bold cyan]Processing command...[/bold cyan]", spinner="dots") as status:
|
|
259
|
-
counter = 0
|
|
260
|
-
while agent_thread.is_alive():
|
|
261
|
-
# Handle any number of clarification requests
|
|
262
|
-
with contextlib.suppress(Empty):
|
|
263
|
-
while True:
|
|
264
|
-
prompt_text = clarification_request_queue.get_nowait()
|
|
265
|
-
# Stop spinner so prompt renders cleanly
|
|
266
|
-
status.stop()
|
|
267
|
-
console.print(f"[bold yellow]Agent -> User> {prompt_text}[/bold yellow]")
|
|
268
|
-
user_answer = prompt_session.prompt("User > ")
|
|
269
|
-
clarification_response_queue.put(user_answer)
|
|
270
|
-
time.sleep(0.3)
|
|
271
|
-
counter += 1
|
|
272
|
-
if counter % 3 == 0:
|
|
273
|
-
status.update(
|
|
274
|
-
f"[bold cyan]Processing command... ({counter // 3}s)[/bold cyan]"
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
# Agent finished work
|
|
278
|
-
agent_thread.join()
|
|
279
|
-
|
|
280
|
-
# Check for errors or display response
|
|
281
|
-
if agent_response_container["error"]:
|
|
282
|
-
raise agent_response_container["error"]
|
|
283
|
-
|
|
284
|
-
if agent_response_container["response"]:
|
|
285
|
-
console.print(Panel(agent_response_container["response"].final_answer,
|
|
286
|
-
title="[bold green]Agent Response[/bold green]",
|
|
287
|
-
border_style="green"))
|
|
288
|
-
|
|
289
|
-
except Exception as e: # pylint: disable=broad-except
|
|
290
|
-
console.print(f"[bold red]Agent Error:[/bold red] An error occurred during agent processing: {e}")
|
|
291
|
-
|
|
292
|
-
if __name__ == "__main__":
|
|
293
|
-
print("Loading fastWorkflow...\n")
|
|
294
|
-
main()
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# fastworkflow/run_agent/agent_module.py
|
|
2
|
-
"""
|
|
3
|
-
High-level planning agent module for fastWorkflow.
|
|
4
|
-
Uses the integrated workflow tool agent from ChatSession.
|
|
5
|
-
"""
|
|
6
|
-
import functools
|
|
7
|
-
import os
|
|
8
|
-
from queue import Queue
|
|
9
|
-
from typing import Any, Optional, List, Dict
|
|
10
|
-
|
|
11
|
-
import dspy
|
|
12
|
-
from colorama import Fore, Style
|
|
13
|
-
|
|
14
|
-
import fastworkflow
|
|
15
|
-
from fastworkflow.mcp_server import FastWorkflowMCPServer
|
|
16
|
-
|
|
17
|
-
# Queues used to synchronise clarification requests between the agent thread
|
|
18
|
-
# (where `_ask_user_tool` is executed) and the main thread that owns the TTY.
|
|
19
|
-
clarification_request_queue: Queue[str] = Queue()
|
|
20
|
-
clarification_response_queue: Queue[str] = Queue()
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# DSPy Signature for the High-Level Planning Agent
|
|
24
|
-
class PlanningAgentSignature(dspy.Signature):
|
|
25
|
-
"""
|
|
26
|
-
Create a minimal step based todo list based only on the commands in the user query
|
|
27
|
-
Then, execute the plan for building the final answer using the WorkflowAssistant tool.
|
|
28
|
-
Double-check that all the tasks in the todo list have been completed before returning the final answer.
|
|
29
|
-
"""
|
|
30
|
-
user_query = dspy.InputField(desc="The user's full input or question.")
|
|
31
|
-
final_answer = dspy.OutputField(desc="The agent's comprehensive response to the user after interacting with the workflow.")
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _format_workflow_output_for_agent(command_output: Any) -> str:
|
|
35
|
-
"""
|
|
36
|
-
Formats the structured CommandOutput from the workflow into a single string for the agent.
|
|
37
|
-
Handles both regular command responses and MCP tool results.
|
|
38
|
-
"""
|
|
39
|
-
# Check if this is an MCP result converted to CommandOutput
|
|
40
|
-
if hasattr(command_output, '_mcp_source'):
|
|
41
|
-
return _format_mcp_result_for_agent(command_output._mcp_source)
|
|
42
|
-
|
|
43
|
-
# Otherwise use existing logic for regular command responses
|
|
44
|
-
output_parts = []
|
|
45
|
-
if not hasattr(command_output, 'command_responses') or not command_output.command_responses:
|
|
46
|
-
return "Workflow produced no command responses or the response structure is unexpected."
|
|
47
|
-
|
|
48
|
-
for command_response in command_output.command_responses:
|
|
49
|
-
if response_text := getattr(command_response, 'response', None):
|
|
50
|
-
output_parts.append(f"{response_text}")
|
|
51
|
-
|
|
52
|
-
artifacts = getattr(command_response, 'artifacts', {})
|
|
53
|
-
output_parts.extend(
|
|
54
|
-
f"Artifact: {artifact_name}={artifact_value}"
|
|
55
|
-
for artifact_name, artifact_value in artifacts.items()
|
|
56
|
-
)
|
|
57
|
-
next_actions = getattr(command_response, 'next_actions', [])
|
|
58
|
-
output_parts.extend(f"Next Action: {action}" for action in next_actions)
|
|
59
|
-
|
|
60
|
-
recommendations = getattr(command_response, 'recommendations', [])
|
|
61
|
-
output_parts.extend(
|
|
62
|
-
f"Recommendation: {recommendation}"
|
|
63
|
-
for recommendation in recommendations
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
if not output_parts:
|
|
67
|
-
return "Workflow executed but produced no specific output, actions, or recommendations."
|
|
68
|
-
return "\n".join(output_parts)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def _format_mcp_result_for_agent(mcp_result) -> str:
|
|
72
|
-
"""Format MCPToolResult specifically for agent consumption"""
|
|
73
|
-
if mcp_result.isError:
|
|
74
|
-
return f"Error: {mcp_result.content[0].text}"
|
|
75
|
-
else:
|
|
76
|
-
return mcp_result.content[0].text
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def _build_assistant_tool_documentation(available_tools: List[Dict]) -> str:
|
|
80
|
-
"""Build simplified tool documentation for the main agent's WorkflowAssistant tool."""
|
|
81
|
-
|
|
82
|
-
# Guidance for the MAIN AGENT on how to call WorkflowAssistant
|
|
83
|
-
main_agent_guidance = """
|
|
84
|
-
Use the WorkflowAssistant to interact with a suite of underlying tools to assist the user.
|
|
85
|
-
It takes a natural language query as input and delegates to an internal agent
|
|
86
|
-
that will try to understand the request, select the most appropriate tool, and execute it.
|
|
87
|
-
In normal mode: Example tool_args: {"tool_request": "<A single tool request with tool description and all required input parameter names and values>"}
|
|
88
|
-
If workflow assistant reports back with parameter extraction errors: Example tool_args: {"tool_request": "<A strictly comma delimited list of just the requested parameter values>"}
|
|
89
|
-
|
|
90
|
-
Available tools that WorkflowAssistant can access:
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
tool_docs = []
|
|
94
|
-
for tool_def in available_tools:
|
|
95
|
-
tool_name = tool_def['name']
|
|
96
|
-
tool_desc = tool_def['description'].split("\n")[0]
|
|
97
|
-
|
|
98
|
-
# Main agent does not need the detailed input schema, only name, description and parameters.
|
|
99
|
-
tool_docs.append(
|
|
100
|
-
f"\nTool Name: \"{tool_name}\""
|
|
101
|
-
f"\nDescription: {tool_desc}"
|
|
102
|
-
f"\nRequired Parameters: {tool_def['inputSchema']['required']}"
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
return main_agent_guidance + "\n".join(tool_docs)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def _execute_workflow_command_tool_with_delegation(tool_request: str,
|
|
109
|
-
*,
|
|
110
|
-
chat_session: fastworkflow.ChatSession,
|
|
111
|
-
**kwargs) -> str:
|
|
112
|
-
"""
|
|
113
|
-
Delegate tool requests to the workflow via queues.
|
|
114
|
-
This is used by the high-level planning agent in run_agent.
|
|
115
|
-
"""
|
|
116
|
-
print(f"{Fore.CYAN}{Style.BRIGHT}Agent -> Workflow>{Style.RESET_ALL}{Fore.CYAN} {tool_request}{Style.RESET_ALL}")
|
|
117
|
-
|
|
118
|
-
if extras := " ".join(f"{k}={v}" for k, v in kwargs.items()):
|
|
119
|
-
# Send the request through the user message queue
|
|
120
|
-
chat_session.user_message_queue.put(f"{tool_request} {extras}")
|
|
121
|
-
else:
|
|
122
|
-
# Send the request through the user message queue
|
|
123
|
-
chat_session.user_message_queue.put(tool_request)
|
|
124
|
-
|
|
125
|
-
# Get the response from the command output queue
|
|
126
|
-
command_output = chat_session.command_output_queue.get()
|
|
127
|
-
|
|
128
|
-
# Format the output for the agent
|
|
129
|
-
result = _format_workflow_output_for_agent(command_output)
|
|
130
|
-
|
|
131
|
-
print(f"{Fore.BLUE}{Style.BRIGHT}Workflow -> Agent>{Style.RESET_ALL}{Fore.BLUE} {result.replace(os.linesep, ' ')}{Style.RESET_ALL}")
|
|
132
|
-
return result
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def _ask_user_tool(prompt: str) -> str:
|
|
136
|
-
"""Request extra information from the human user.
|
|
137
|
-
|
|
138
|
-
Because the agent runs in a background thread, we cannot read from
|
|
139
|
-
`stdin` here. Instead we send the prompt to the main thread via a
|
|
140
|
-
queue and block until the main thread puts the user's answer in the
|
|
141
|
-
response queue.
|
|
142
|
-
"""
|
|
143
|
-
# Send the prompt to the main thread
|
|
144
|
-
clarification_request_queue.put(prompt)
|
|
145
|
-
|
|
146
|
-
return clarification_response_queue.get()
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def initialize_dspy_agent(chat_session: fastworkflow.ChatSession, max_iters: int = 25):
|
|
150
|
-
"""
|
|
151
|
-
Configures and returns a high-level DSPy ReAct planning agent.
|
|
152
|
-
The workflow tool agent is already integrated in the ChatSession.
|
|
153
|
-
|
|
154
|
-
Args:
|
|
155
|
-
chat_session: ChatSession instance (should be in agent mode)
|
|
156
|
-
max_iters: Maximum iterations for the ReAct agent
|
|
157
|
-
|
|
158
|
-
Raises:
|
|
159
|
-
EnvironmentError: If LLM_AGENT is not set.
|
|
160
|
-
"""
|
|
161
|
-
# Get available tools for documentation
|
|
162
|
-
mcp_server = FastWorkflowMCPServer(chat_session)
|
|
163
|
-
available_tools = mcp_server.list_tools()
|
|
164
|
-
|
|
165
|
-
# WorkflowAssistant Tool - delegates to the integrated workflow tool agent
|
|
166
|
-
_workflow_assistant_partial_func = functools.partial(
|
|
167
|
-
_execute_workflow_command_tool_with_delegation,
|
|
168
|
-
chat_session=chat_session
|
|
169
|
-
)
|
|
170
|
-
# Set the docstring for the partial object
|
|
171
|
-
_workflow_assistant_partial_func.__doc__ = _build_assistant_tool_documentation(available_tools)
|
|
172
|
-
|
|
173
|
-
workflow_assistant_instance = dspy.Tool(
|
|
174
|
-
name="WorkflowAssistant",
|
|
175
|
-
func=_workflow_assistant_partial_func
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
# AskUser Tool
|
|
179
|
-
_ask_user_tool.__doc__ = (
|
|
180
|
-
"Use this tool to get information from the user. "
|
|
181
|
-
"Use it as the last resort if information is not available via any of the other tools. "
|
|
182
|
-
"Args: prompt (str): A clear specific request with helpful context based on the information already gathered."
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
ask_user_instance = dspy.Tool(
|
|
186
|
-
name="AskUser",
|
|
187
|
-
func=_ask_user_tool
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
return dspy.ReAct(
|
|
191
|
-
PlanningAgentSignature,
|
|
192
|
-
tools=[workflow_assistant_instance, ask_user_instance],
|
|
193
|
-
max_iters=max_iters,
|
|
194
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|