griptape-nodes 0.43.1__py3-none-any.whl → 0.44.0__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.
- griptape_nodes/__init__.py +41 -51
- griptape_nodes/app/.python-version +0 -0
- griptape_nodes/app/__init__.py +0 -0
- griptape_nodes/app/api.py +35 -6
- griptape_nodes/app/app.py +0 -0
- griptape_nodes/app/watch.py +0 -0
- griptape_nodes/bootstrap/__init__.py +0 -0
- griptape_nodes/bootstrap/workflow_executors/__init__.py +0 -0
- griptape_nodes/bootstrap/workflow_executors/local_workflow_executor.py +7 -1
- griptape_nodes/bootstrap/workflow_executors/subprocess_workflow_executor.py +90 -0
- griptape_nodes/bootstrap/workflow_executors/workflow_executor.py +7 -1
- griptape_nodes/drivers/__init__.py +0 -0
- griptape_nodes/drivers/storage/__init__.py +0 -0
- griptape_nodes/drivers/storage/base_storage_driver.py +53 -0
- griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +49 -2
- griptape_nodes/drivers/storage/local_storage_driver.py +37 -0
- griptape_nodes/drivers/storage/storage_backend.py +0 -0
- griptape_nodes/exe_types/__init__.py +0 -0
- griptape_nodes/exe_types/connections.py +0 -0
- griptape_nodes/exe_types/core_types.py +113 -8
- griptape_nodes/exe_types/flow.py +0 -0
- griptape_nodes/exe_types/node_types.py +1 -0
- griptape_nodes/exe_types/type_validator.py +0 -0
- griptape_nodes/machines/__init__.py +0 -0
- griptape_nodes/machines/control_flow.py +5 -4
- griptape_nodes/machines/fsm.py +0 -0
- griptape_nodes/machines/node_resolution.py +110 -74
- griptape_nodes/mcp_server/__init__.py +0 -0
- griptape_nodes/mcp_server/server.py +16 -8
- griptape_nodes/mcp_server/ws_request_manager.py +0 -0
- griptape_nodes/node_library/__init__.py +0 -0
- griptape_nodes/node_library/advanced_node_library.py +0 -0
- griptape_nodes/node_library/library_registry.py +0 -0
- griptape_nodes/node_library/workflow_registry.py +0 -0
- griptape_nodes/py.typed +0 -0
- griptape_nodes/retained_mode/__init__.py +0 -0
- griptape_nodes/retained_mode/events/__init__.py +0 -0
- griptape_nodes/retained_mode/events/agent_events.py +0 -0
- griptape_nodes/retained_mode/events/app_events.py +0 -6
- griptape_nodes/retained_mode/events/arbitrary_python_events.py +0 -0
- griptape_nodes/retained_mode/events/base_events.py +6 -7
- griptape_nodes/retained_mode/events/config_events.py +0 -0
- griptape_nodes/retained_mode/events/connection_events.py +0 -0
- griptape_nodes/retained_mode/events/context_events.py +0 -0
- griptape_nodes/retained_mode/events/execution_events.py +0 -0
- griptape_nodes/retained_mode/events/flow_events.py +2 -1
- griptape_nodes/retained_mode/events/generate_request_payload_schemas.py +0 -0
- griptape_nodes/retained_mode/events/library_events.py +0 -0
- griptape_nodes/retained_mode/events/logger_events.py +0 -0
- griptape_nodes/retained_mode/events/node_events.py +36 -0
- griptape_nodes/retained_mode/events/object_events.py +0 -0
- griptape_nodes/retained_mode/events/os_events.py +98 -6
- griptape_nodes/retained_mode/events/parameter_events.py +0 -0
- griptape_nodes/retained_mode/events/payload_registry.py +0 -0
- griptape_nodes/retained_mode/events/secrets_events.py +0 -0
- griptape_nodes/retained_mode/events/static_file_events.py +0 -0
- griptape_nodes/retained_mode/events/validation_events.py +0 -0
- griptape_nodes/retained_mode/events/workflow_events.py +0 -0
- griptape_nodes/retained_mode/griptape_nodes.py +1 -4
- griptape_nodes/retained_mode/managers/__init__.py +0 -0
- griptape_nodes/retained_mode/managers/agent_manager.py +0 -0
- griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py +0 -0
- griptape_nodes/retained_mode/managers/config_manager.py +1 -1
- griptape_nodes/retained_mode/managers/context_manager.py +0 -0
- griptape_nodes/retained_mode/managers/engine_identity_manager.py +0 -0
- griptape_nodes/retained_mode/managers/event_manager.py +0 -0
- griptape_nodes/retained_mode/managers/flow_manager.py +6 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_directory.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_fsm.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/__init__.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/base.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/github.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/local_file.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/package.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py +0 -0
- griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py +0 -0
- griptape_nodes/retained_mode/managers/library_manager.py +2 -8
- griptape_nodes/retained_mode/managers/node_manager.py +76 -5
- griptape_nodes/retained_mode/managers/object_manager.py +0 -0
- griptape_nodes/retained_mode/managers/operation_manager.py +0 -0
- griptape_nodes/retained_mode/managers/os_manager.py +133 -8
- griptape_nodes/retained_mode/managers/secrets_manager.py +0 -0
- griptape_nodes/retained_mode/managers/session_manager.py +0 -0
- griptape_nodes/retained_mode/managers/settings.py +0 -0
- griptape_nodes/retained_mode/managers/static_files_manager.py +0 -0
- griptape_nodes/retained_mode/managers/version_compatibility_manager.py +0 -0
- griptape_nodes/retained_mode/managers/workflow_manager.py +54 -5
- griptape_nodes/retained_mode/retained_mode.py +0 -0
- griptape_nodes/retained_mode/utils/__init__.py +0 -0
- griptape_nodes/retained_mode/utils/engine_identity.py +0 -0
- griptape_nodes/retained_mode/utils/name_generator.py +0 -0
- griptape_nodes/traits/__init__.py +0 -0
- griptape_nodes/traits/add_param_button.py +0 -0
- griptape_nodes/traits/button.py +0 -0
- griptape_nodes/traits/clamp.py +0 -0
- griptape_nodes/traits/compare.py +0 -0
- griptape_nodes/traits/compare_images.py +0 -0
- griptape_nodes/traits/file_system_picker.py +18 -0
- griptape_nodes/traits/minmax.py +0 -0
- griptape_nodes/traits/options.py +0 -0
- griptape_nodes/traits/slider.py +0 -0
- griptape_nodes/traits/trait_registry.py +0 -0
- griptape_nodes/traits/traits.json +0 -0
- griptape_nodes/updater/__init__.py +0 -0
- griptape_nodes/updater/__main__.py +0 -0
- griptape_nodes/utils/__init__.py +0 -0
- griptape_nodes/utils/dict_utils.py +0 -0
- griptape_nodes/utils/image_preview.py +0 -0
- griptape_nodes/utils/metaclasses.py +0 -0
- griptape_nodes/utils/version_utils.py +51 -0
- griptape_nodes/version_compatibility/__init__.py +0 -0
- griptape_nodes/version_compatibility/versions/__init__.py +0 -0
- griptape_nodes/version_compatibility/versions/v0_39_0/__init__.py +0 -0
- griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_removal.py +0 -0
- {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.44.0.dist-info}/METADATA +1 -1
- {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.44.0.dist-info}/RECORD +31 -39
- {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.44.0.dist-info}/WHEEL +1 -1
- griptape_nodes/bootstrap/bootstrap_script.py +0 -54
- griptape_nodes/bootstrap/post_build_install_script.sh +0 -3
- griptape_nodes/bootstrap/pre_build_install_script.sh +0 -4
- griptape_nodes/bootstrap/register_libraries_script.py +0 -32
- griptape_nodes/bootstrap/structure_config.yaml +0 -15
- griptape_nodes/bootstrap/workflow_runners/__init__.py +0 -1
- griptape_nodes/bootstrap/workflow_runners/bootstrap_workflow_runner.py +0 -28
- griptape_nodes/bootstrap/workflow_runners/local_workflow_runner.py +0 -237
- griptape_nodes/bootstrap/workflow_runners/subprocess_workflow_runner.py +0 -62
- griptape_nodes/bootstrap/workflow_runners/workflow_runner.py +0 -11
- {griptape_nodes-0.43.1.dist-info → griptape_nodes-0.44.0.dist-info}/entry_points.txt +0 -0
|
@@ -244,6 +244,11 @@ class BaseNodeElement:
|
|
|
244
244
|
"name": self.name,
|
|
245
245
|
"node_name": self._node_context.name,
|
|
246
246
|
}
|
|
247
|
+
# If ui_options changed, send the complete ui_options from to_dict()
|
|
248
|
+
complete_dict = self.to_dict()
|
|
249
|
+
if "ui_options" in complete_dict:
|
|
250
|
+
self._changes["ui_options"] = complete_dict["ui_options"]
|
|
251
|
+
|
|
247
252
|
event_data.update(self._changes)
|
|
248
253
|
|
|
249
254
|
# Publish the event
|
|
@@ -384,13 +389,97 @@ class ParameterMessage(BaseNodeElement):
|
|
|
384
389
|
type VariantType = Literal["info", "warning", "error", "success", "tip", "none"]
|
|
385
390
|
|
|
386
391
|
element_type: str = field(default_factory=lambda: ParameterMessage.__name__)
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
392
|
+
_variant: VariantType = field(init=False)
|
|
393
|
+
_title: str | None = field(default=None, init=False)
|
|
394
|
+
_value: str = field(init=False)
|
|
395
|
+
_button_link: str | None = field(default=None, init=False)
|
|
396
|
+
_button_text: str | None = field(default=None, init=False)
|
|
397
|
+
_full_width: bool = field(default=False, init=False)
|
|
398
|
+
_ui_options: dict = field(default_factory=dict, init=False)
|
|
399
|
+
|
|
400
|
+
def __init__( # noqa: PLR0913
|
|
401
|
+
self,
|
|
402
|
+
variant: VariantType,
|
|
403
|
+
value: str,
|
|
404
|
+
*,
|
|
405
|
+
title: str | None = None,
|
|
406
|
+
button_link: str | None = None,
|
|
407
|
+
button_text: str | None = None,
|
|
408
|
+
full_width: bool = False,
|
|
409
|
+
ui_options: dict | None = None,
|
|
410
|
+
**kwargs,
|
|
411
|
+
):
|
|
412
|
+
super().__init__(element_type=ParameterMessage.__name__, **kwargs)
|
|
413
|
+
self._variant = variant
|
|
414
|
+
self._title = title
|
|
415
|
+
self._value = value
|
|
416
|
+
self._button_link = button_link
|
|
417
|
+
self._button_text = button_text
|
|
418
|
+
self._full_width = full_width
|
|
419
|
+
self._ui_options = ui_options or {}
|
|
420
|
+
|
|
421
|
+
@property
|
|
422
|
+
def variant(self) -> VariantType:
|
|
423
|
+
return self._variant
|
|
424
|
+
|
|
425
|
+
@variant.setter
|
|
426
|
+
@BaseNodeElement.emits_update_on_write
|
|
427
|
+
def variant(self, value: VariantType) -> None:
|
|
428
|
+
self._variant = value
|
|
429
|
+
|
|
430
|
+
@property
|
|
431
|
+
def title(self) -> str | None:
|
|
432
|
+
return self._title
|
|
433
|
+
|
|
434
|
+
@title.setter
|
|
435
|
+
@BaseNodeElement.emits_update_on_write
|
|
436
|
+
def title(self, value: str | None) -> None:
|
|
437
|
+
self._title = value
|
|
438
|
+
|
|
439
|
+
@property
|
|
440
|
+
def value(self) -> str:
|
|
441
|
+
return self._value
|
|
442
|
+
|
|
443
|
+
@value.setter
|
|
444
|
+
@BaseNodeElement.emits_update_on_write
|
|
445
|
+
def value(self, value: str) -> None:
|
|
446
|
+
self._value = value
|
|
447
|
+
|
|
448
|
+
@property
|
|
449
|
+
def button_link(self) -> str | None:
|
|
450
|
+
return self._button_link
|
|
451
|
+
|
|
452
|
+
@button_link.setter
|
|
453
|
+
@BaseNodeElement.emits_update_on_write
|
|
454
|
+
def button_link(self, value: str | None) -> None:
|
|
455
|
+
self._button_link = value
|
|
456
|
+
|
|
457
|
+
@property
|
|
458
|
+
def button_text(self) -> str | None:
|
|
459
|
+
return self._button_text
|
|
460
|
+
|
|
461
|
+
@button_text.setter
|
|
462
|
+
@BaseNodeElement.emits_update_on_write
|
|
463
|
+
def button_text(self, value: str | None) -> None:
|
|
464
|
+
self._button_text = value
|
|
465
|
+
|
|
466
|
+
@property
|
|
467
|
+
def full_width(self) -> bool:
|
|
468
|
+
return self._full_width
|
|
469
|
+
|
|
470
|
+
@full_width.setter
|
|
471
|
+
@BaseNodeElement.emits_update_on_write
|
|
472
|
+
def full_width(self, value: bool) -> None:
|
|
473
|
+
self._full_width = value
|
|
474
|
+
|
|
475
|
+
@property
|
|
476
|
+
def ui_options(self) -> dict:
|
|
477
|
+
return self._ui_options
|
|
478
|
+
|
|
479
|
+
@ui_options.setter
|
|
480
|
+
@BaseNodeElement.emits_update_on_write
|
|
481
|
+
def ui_options(self, value: dict) -> None:
|
|
482
|
+
self._ui_options = value
|
|
394
483
|
|
|
395
484
|
def to_dict(self) -> dict[str, Any]:
|
|
396
485
|
data = super().to_dict()
|
|
@@ -594,7 +683,7 @@ class Parameter(BaseNodeElement):
|
|
|
594
683
|
if not element_id:
|
|
595
684
|
element_id = str(uuid.uuid4().hex)
|
|
596
685
|
if not element_type:
|
|
597
|
-
element_type =
|
|
686
|
+
element_type = self.__class__.__name__
|
|
598
687
|
super().__init__(element_id=element_id, element_type=element_type)
|
|
599
688
|
self.name = name
|
|
600
689
|
self.tooltip = tooltip
|
|
@@ -951,6 +1040,7 @@ class ControlParameter(Parameter, ABC):
|
|
|
951
1040
|
traits: set[Trait.__class__ | Trait] | None = None,
|
|
952
1041
|
converters: list[Callable[[Any], Any]] | None = None,
|
|
953
1042
|
validators: list[Callable[[Parameter, Any], None]] | None = None,
|
|
1043
|
+
ui_options: dict | None = None,
|
|
954
1044
|
*,
|
|
955
1045
|
user_defined: bool = False,
|
|
956
1046
|
):
|
|
@@ -970,6 +1060,7 @@ class ControlParameter(Parameter, ABC):
|
|
|
970
1060
|
traits=traits,
|
|
971
1061
|
converters=converters,
|
|
972
1062
|
validators=validators,
|
|
1063
|
+
ui_options=ui_options,
|
|
973
1064
|
user_defined=user_defined,
|
|
974
1065
|
element_type=self.__class__.__name__,
|
|
975
1066
|
)
|
|
@@ -980,6 +1071,7 @@ class ControlParameterInput(ControlParameter):
|
|
|
980
1071
|
self,
|
|
981
1072
|
tooltip: str | list[dict] = "Connection from previous node in the execution chain",
|
|
982
1073
|
name: str = "exec_in",
|
|
1074
|
+
display_name: str | None = "Flow In",
|
|
983
1075
|
tooltip_as_input: str | list[dict] | None = None,
|
|
984
1076
|
tooltip_as_property: str | list[dict] | None = None,
|
|
985
1077
|
tooltip_as_output: str | list[dict] | None = None,
|
|
@@ -992,6 +1084,11 @@ class ControlParameterInput(ControlParameter):
|
|
|
992
1084
|
allowed_modes = {ParameterMode.INPUT}
|
|
993
1085
|
input_types = [ParameterTypeBuiltin.CONTROL_TYPE.value]
|
|
994
1086
|
|
|
1087
|
+
if display_name is None:
|
|
1088
|
+
ui_options = None
|
|
1089
|
+
else:
|
|
1090
|
+
ui_options = {"display_name": display_name}
|
|
1091
|
+
|
|
995
1092
|
# Call parent with a few explicit tweaks.
|
|
996
1093
|
super().__init__(
|
|
997
1094
|
name=name,
|
|
@@ -1005,6 +1102,7 @@ class ControlParameterInput(ControlParameter):
|
|
|
1005
1102
|
traits=traits,
|
|
1006
1103
|
converters=converters,
|
|
1007
1104
|
validators=validators,
|
|
1105
|
+
ui_options=ui_options,
|
|
1008
1106
|
user_defined=user_defined,
|
|
1009
1107
|
)
|
|
1010
1108
|
|
|
@@ -1014,6 +1112,7 @@ class ControlParameterOutput(ControlParameter):
|
|
|
1014
1112
|
self,
|
|
1015
1113
|
tooltip: str | list[dict] = "Connection to the next node in the execution chain",
|
|
1016
1114
|
name: str = "exec_out",
|
|
1115
|
+
display_name: str | None = "Flow Out",
|
|
1017
1116
|
tooltip_as_input: str | list[dict] | None = None,
|
|
1018
1117
|
tooltip_as_property: str | list[dict] | None = None,
|
|
1019
1118
|
tooltip_as_output: str | list[dict] | None = None,
|
|
@@ -1026,6 +1125,11 @@ class ControlParameterOutput(ControlParameter):
|
|
|
1026
1125
|
allowed_modes = {ParameterMode.OUTPUT}
|
|
1027
1126
|
output_type = ParameterTypeBuiltin.CONTROL_TYPE.value
|
|
1028
1127
|
|
|
1128
|
+
if display_name is None:
|
|
1129
|
+
ui_options = None
|
|
1130
|
+
else:
|
|
1131
|
+
ui_options = {"display_name": display_name}
|
|
1132
|
+
|
|
1029
1133
|
# Call parent with a few explicit tweaks.
|
|
1030
1134
|
super().__init__(
|
|
1031
1135
|
name=name,
|
|
@@ -1039,6 +1143,7 @@ class ControlParameterOutput(ControlParameter):
|
|
|
1039
1143
|
traits=traits,
|
|
1040
1144
|
converters=converters,
|
|
1041
1145
|
validators=validators,
|
|
1146
|
+
ui_options=ui_options,
|
|
1042
1147
|
user_defined=user_defined,
|
|
1043
1148
|
)
|
|
1044
1149
|
|
griptape_nodes/exe_types/flow.py
CHANGED
|
File without changes
|
|
@@ -68,6 +68,7 @@ class BaseNode(ABC):
|
|
|
68
68
|
_entry_control_parameter: Parameter | None = (
|
|
69
69
|
None # The control input parameter used to enter this node during execution
|
|
70
70
|
)
|
|
71
|
+
lock: bool = False # When lock is true, the node is locked and can't be modified. When lock is false, the node is unlocked and can be modified.
|
|
71
72
|
|
|
72
73
|
@property
|
|
73
74
|
def parameters(self) -> list[Parameter]:
|
|
File without changes
|
|
File without changes
|
|
@@ -88,11 +88,12 @@ class ResolveNodeState(State):
|
|
|
88
88
|
return CompleteState
|
|
89
89
|
|
|
90
90
|
# Mark the node unresolved, and broadcast an event to the GUI.
|
|
91
|
-
context.current_node.
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
if not context.current_node.lock:
|
|
92
|
+
context.current_node.make_node_unresolved(
|
|
93
|
+
current_states_to_trigger_change_event=set(
|
|
94
|
+
{NodeResolutionState.UNRESOLVED, NodeResolutionState.RESOLVED, NodeResolutionState.RESOLVING}
|
|
95
|
+
)
|
|
94
96
|
)
|
|
95
|
-
)
|
|
96
97
|
# Now broadcast that we have a current control node.
|
|
97
98
|
EventBus.publish_event(
|
|
98
99
|
ExecutionGriptapeNodeEvent(
|
griptape_nodes/machines/fsm.py
CHANGED
|
File without changes
|
|
@@ -195,10 +195,56 @@ class ExecuteNodeState(State):
|
|
|
195
195
|
EventBus.publish_event(ExecutionGriptapeNodeEvent(wrapped_event=ExecutionEvent(payload=payload)))
|
|
196
196
|
current_node.parameter_output_values.clear()
|
|
197
197
|
|
|
198
|
+
@staticmethod
|
|
199
|
+
def collect_values_from_upstream_nodes(context: ResolutionContext) -> None:
|
|
200
|
+
"""Collect output values from resolved upstream nodes and pass them to the current node.
|
|
201
|
+
|
|
202
|
+
This method iterates through all input parameters of the current node, finds their
|
|
203
|
+
connected upstream nodes, and if those nodes are resolved, retrieves their output
|
|
204
|
+
values and passes them through using SetParameterValueRequest.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
context (ResolutionContext): The resolution context containing the focus stack
|
|
208
|
+
with the current node being processed.
|
|
209
|
+
"""
|
|
210
|
+
from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
|
|
211
|
+
|
|
212
|
+
current_node = context.focus_stack[-1].node
|
|
213
|
+
connections = GriptapeNodes.FlowManager().get_connections()
|
|
214
|
+
|
|
215
|
+
for parameter in current_node.parameters:
|
|
216
|
+
# Skip control type parameters
|
|
217
|
+
if ParameterTypeBuiltin.CONTROL_TYPE.value.lower() == parameter.output_type:
|
|
218
|
+
continue
|
|
219
|
+
|
|
220
|
+
# Get the connected upstream node for this parameter
|
|
221
|
+
upstream_connection = connections.get_connected_node(current_node, parameter)
|
|
222
|
+
if upstream_connection:
|
|
223
|
+
upstream_node, upstream_parameter = upstream_connection
|
|
224
|
+
|
|
225
|
+
# If the upstream node is resolved, collect its output value
|
|
226
|
+
if upstream_parameter.name in upstream_node.parameter_output_values:
|
|
227
|
+
output_value = upstream_node.parameter_output_values[upstream_parameter.name]
|
|
228
|
+
|
|
229
|
+
# Pass the value through using the same mechanism as normal resolution
|
|
230
|
+
GriptapeNodes.get_instance().handle_request(
|
|
231
|
+
SetParameterValueRequest(
|
|
232
|
+
parameter_name=parameter.name,
|
|
233
|
+
node_name=current_node.name,
|
|
234
|
+
value=output_value,
|
|
235
|
+
data_type=upstream_parameter.output_type,
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
|
|
198
239
|
@staticmethod
|
|
199
240
|
def on_enter(context: ResolutionContext) -> type[State] | None:
|
|
200
241
|
current_node = context.focus_stack[-1].node
|
|
242
|
+
|
|
201
243
|
# Clear all of the current output values
|
|
244
|
+
# if node is locked, don't clear anything. skip all of this.
|
|
245
|
+
if current_node.lock:
|
|
246
|
+
return ExecuteNodeState
|
|
247
|
+
ExecuteNodeState.collect_values_from_upstream_nodes(context)
|
|
202
248
|
ExecuteNodeState.clear_parameter_output_values(context)
|
|
203
249
|
for parameter in current_node.parameters:
|
|
204
250
|
if ParameterTypeBuiltin.CONTROL_TYPE.value.lower() == parameter.output_type:
|
|
@@ -244,95 +290,85 @@ class ExecuteNodeState(State):
|
|
|
244
290
|
# Once everything has been set
|
|
245
291
|
current_focus = context.focus_stack[-1]
|
|
246
292
|
current_node = current_focus.node
|
|
247
|
-
#
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
wrapped_event=ExecutionEvent(payload=NodeStartProcessEvent(node_name=current_node.name))
|
|
251
|
-
)
|
|
252
|
-
)
|
|
253
|
-
logger.info("Node '%s' is processing.", current_node.name)
|
|
254
|
-
|
|
255
|
-
try:
|
|
256
|
-
work_is_scheduled = ExecuteNodeState._process_node(current_focus)
|
|
257
|
-
if work_is_scheduled:
|
|
258
|
-
logger.debug("Pausing Node '%s' to run background work", current_node.name)
|
|
259
|
-
return None
|
|
260
|
-
except Exception as e:
|
|
261
|
-
logger.exception("Error processing node '%s", current_node.name)
|
|
262
|
-
msg = f"Canceling flow run. Node '{current_node.name}' encountered a problem: {e}"
|
|
263
|
-
# Mark the node as unresolved, broadcasting to everyone.
|
|
264
|
-
current_node.make_node_unresolved(
|
|
265
|
-
current_states_to_trigger_change_event=set(
|
|
266
|
-
{NodeResolutionState.UNRESOLVED, NodeResolutionState.RESOLVED, NodeResolutionState.RESOLVING}
|
|
267
|
-
)
|
|
268
|
-
)
|
|
269
|
-
current_focus.process_generator = None
|
|
270
|
-
current_focus.scheduled_value = None
|
|
271
|
-
|
|
272
|
-
from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
|
|
273
|
-
|
|
274
|
-
GriptapeNodes.FlowManager().cancel_flow_run()
|
|
275
|
-
|
|
293
|
+
# If the node is not locked, execute all of this.
|
|
294
|
+
if not current_node.lock:
|
|
295
|
+
# To set the event manager without circular import errors
|
|
276
296
|
EventBus.publish_event(
|
|
277
297
|
ExecutionGriptapeNodeEvent(
|
|
278
|
-
wrapped_event=ExecutionEvent(payload=
|
|
298
|
+
wrapped_event=ExecutionEvent(payload=NodeStartProcessEvent(node_name=current_node.name))
|
|
279
299
|
)
|
|
280
300
|
)
|
|
281
|
-
|
|
301
|
+
logger.info("Node '%s' is processing.", current_node.name)
|
|
282
302
|
|
|
283
|
-
|
|
303
|
+
try:
|
|
304
|
+
work_is_scheduled = ExecuteNodeState._process_node(current_focus)
|
|
305
|
+
if work_is_scheduled:
|
|
306
|
+
logger.debug("Pausing Node '%s' to run background work", current_node.name)
|
|
307
|
+
return None
|
|
308
|
+
except Exception as e:
|
|
309
|
+
logger.exception("Error processing node '%s", current_node.name)
|
|
310
|
+
msg = f"Canceling flow run. Node '{current_node.name}' encountered a problem: {e}"
|
|
311
|
+
# Mark the node as unresolved, broadcasting to everyone.
|
|
312
|
+
current_node.make_node_unresolved(
|
|
313
|
+
current_states_to_trigger_change_event=set(
|
|
314
|
+
{NodeResolutionState.UNRESOLVED, NodeResolutionState.RESOLVED, NodeResolutionState.RESOLVING}
|
|
315
|
+
)
|
|
316
|
+
)
|
|
317
|
+
current_focus.process_generator = None
|
|
318
|
+
current_focus.scheduled_value = None
|
|
284
319
|
|
|
285
|
-
|
|
286
|
-
ExecutionGriptapeNodeEvent(
|
|
287
|
-
wrapped_event=ExecutionEvent(payload=NodeFinishProcessEvent(node_name=current_node.name))
|
|
288
|
-
)
|
|
289
|
-
)
|
|
290
|
-
current_node.state = NodeResolutionState.RESOLVED
|
|
291
|
-
details = f"'{current_node.name}' resolved."
|
|
320
|
+
from griptape_nodes.retained_mode.griptape_nodes import GriptapeNodes
|
|
292
321
|
|
|
293
|
-
|
|
322
|
+
GriptapeNodes.FlowManager().cancel_flow_run()
|
|
294
323
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
324
|
+
EventBus.publish_event(
|
|
325
|
+
ExecutionGriptapeNodeEvent(
|
|
326
|
+
wrapped_event=ExecutionEvent(payload=NodeFinishProcessEvent(node_name=current_node.name))
|
|
327
|
+
)
|
|
328
|
+
)
|
|
329
|
+
raise RuntimeError(msg) from e
|
|
330
|
+
|
|
331
|
+
logger.info("Node '%s' finished processing.", current_node.name)
|
|
302
332
|
|
|
303
|
-
for parameter_name, value in current_node.parameter_output_values.items():
|
|
304
|
-
parameter = current_node.get_parameter_by_name(parameter_name)
|
|
305
|
-
if parameter is None:
|
|
306
|
-
err = f"Canceling flow run. Node '{current_node.name}' specified a Parameter '{parameter_name}', but no such Parameter could be found on that Node."
|
|
307
|
-
raise KeyError(err)
|
|
308
|
-
data_type = parameter.type
|
|
309
|
-
if data_type is None:
|
|
310
|
-
data_type = ParameterTypeBuiltin.NONE.value
|
|
311
333
|
EventBus.publish_event(
|
|
312
334
|
ExecutionGriptapeNodeEvent(
|
|
313
|
-
wrapped_event=ExecutionEvent(
|
|
314
|
-
payload=ParameterValueUpdateEvent(
|
|
315
|
-
node_name=current_node.name,
|
|
316
|
-
parameter_name=parameter_name,
|
|
317
|
-
data_type=data_type,
|
|
318
|
-
value=TypeValidator.safe_serialize(value),
|
|
319
|
-
)
|
|
320
|
-
),
|
|
335
|
+
wrapped_event=ExecutionEvent(payload=NodeFinishProcessEvent(node_name=current_node.name))
|
|
321
336
|
)
|
|
322
337
|
)
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
)
|
|
338
|
+
current_node.state = NodeResolutionState.RESOLVED
|
|
339
|
+
details = f"'{current_node.name}' resolved."
|
|
340
|
+
|
|
341
|
+
logger.info(details)
|
|
342
|
+
|
|
343
|
+
# Serialization can be slow so only do it if the user wants debug details.
|
|
344
|
+
if logger.level <= logging.DEBUG:
|
|
345
|
+
logger.debug(
|
|
346
|
+
"INPUTS: %s\nOUTPUTS: %s",
|
|
347
|
+
TypeValidator.safe_serialize(current_node.parameter_values),
|
|
348
|
+
TypeValidator.safe_serialize(current_node.parameter_output_values),
|
|
333
349
|
)
|
|
334
350
|
|
|
335
|
-
|
|
351
|
+
for parameter_name, value in current_node.parameter_output_values.items():
|
|
352
|
+
parameter = current_node.get_parameter_by_name(parameter_name)
|
|
353
|
+
if parameter is None:
|
|
354
|
+
err = f"Canceling flow run. Node '{current_node.name}' specified a Parameter '{parameter_name}', but no such Parameter could be found on that Node."
|
|
355
|
+
raise KeyError(err)
|
|
356
|
+
data_type = parameter.type
|
|
357
|
+
if data_type is None:
|
|
358
|
+
data_type = ParameterTypeBuiltin.NONE.value
|
|
359
|
+
EventBus.publish_event(
|
|
360
|
+
ExecutionGriptapeNodeEvent(
|
|
361
|
+
wrapped_event=ExecutionEvent(
|
|
362
|
+
payload=ParameterValueUpdateEvent(
|
|
363
|
+
node_name=current_node.name,
|
|
364
|
+
parameter_name=parameter_name,
|
|
365
|
+
data_type=data_type,
|
|
366
|
+
value=TypeValidator.safe_serialize(value),
|
|
367
|
+
)
|
|
368
|
+
),
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
# Output values should already be saved!
|
|
336
372
|
library = LibraryRegistry.get_libraries_with_node_type(current_node.__class__.__name__)
|
|
337
373
|
if len(library) == 1:
|
|
338
374
|
library_name = library[0]
|
|
File without changes
|
|
@@ -57,19 +57,21 @@ SUPPORTED_REQUEST_EVENTS: dict[str, type[RequestPayload]] = {
|
|
|
57
57
|
"SetParameterValueRequest": SetParameterValueRequest,
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
GTN_MCP_SERVER_HOST = os.getenv("GTN_MCP_SERVER_HOST", "localhost")
|
|
60
61
|
GTN_MCP_SERVER_PORT = int(os.getenv("GTN_MCP_SERVER_PORT", "9927"))
|
|
62
|
+
GTN_MCP_SERVER_LOG_LEVEL = os.getenv("GTN_MCP_SERVER_LOG_LEVEL", "ERROR").lower()
|
|
61
63
|
|
|
62
64
|
config_manager = ConfigManager()
|
|
63
65
|
secrets_manager = SecretsManager(config_manager)
|
|
64
66
|
|
|
67
|
+
mcp_server_logger = logging.getLogger("griptape_nodes_mcp_server")
|
|
68
|
+
mcp_server_logger.addHandler(RichHandler(show_time=True, show_path=False, markup=True, rich_tracebacks=True))
|
|
69
|
+
mcp_server_logger.setLevel(logging.INFO)
|
|
70
|
+
|
|
65
71
|
|
|
66
72
|
def main(api_key: str) -> None:
|
|
67
73
|
"""Main entry point for the Griptape Nodes MCP server."""
|
|
68
|
-
mcp_server_logger
|
|
69
|
-
mcp_server_logger.addHandler(RichHandler(show_time=True, show_path=False, markup=True, rich_tracebacks=True))
|
|
70
|
-
mcp_server_logger.setLevel(logging.INFO)
|
|
71
|
-
mcp_server_logger.info("Starting MCP GTN server...")
|
|
72
|
-
|
|
74
|
+
mcp_server_logger.debug("Starting MCP GTN server...")
|
|
73
75
|
# Give these a session ID
|
|
74
76
|
connection_manager = WebSocketConnectionManager()
|
|
75
77
|
request_manager = AsyncRequestManager(connection_manager, api_key)
|
|
@@ -108,11 +110,11 @@ def main(api_key: str) -> None:
|
|
|
108
110
|
async def lifespan(_: FastAPI) -> AsyncIterator[None]:
|
|
109
111
|
"""Context manager for managing session manager lifecycle."""
|
|
110
112
|
async with session_manager.run():
|
|
111
|
-
mcp_server_logger.
|
|
113
|
+
mcp_server_logger.debug("GTN MCP server started with StreamableHTTP session manager!")
|
|
112
114
|
try:
|
|
113
115
|
yield
|
|
114
116
|
finally:
|
|
115
|
-
mcp_server_logger.
|
|
117
|
+
mcp_server_logger.debug("GTN MCP server shutting down...")
|
|
116
118
|
|
|
117
119
|
# Create an ASGI application using the transport
|
|
118
120
|
mcp_server_app = FastAPI(lifespan=lifespan)
|
|
@@ -123,4 +125,10 @@ def main(api_key: str) -> None:
|
|
|
123
125
|
|
|
124
126
|
mcp_server_app.mount("/mcp", app=handle_streamable_http)
|
|
125
127
|
|
|
126
|
-
uvicorn.run(
|
|
128
|
+
uvicorn.run(
|
|
129
|
+
mcp_server_app,
|
|
130
|
+
host=GTN_MCP_SERVER_HOST,
|
|
131
|
+
port=GTN_MCP_SERVER_PORT,
|
|
132
|
+
log_config=None,
|
|
133
|
+
log_level=GTN_MCP_SERVER_LOG_LEVEL,
|
|
134
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
griptape_nodes/py.typed
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -18,15 +18,9 @@ class AppStartSessionRequest(RequestPayload):
|
|
|
18
18
|
Use when: Initializing client connections, beginning new workflow sessions,
|
|
19
19
|
setting up isolated execution environments, managing session state.
|
|
20
20
|
|
|
21
|
-
Args:
|
|
22
|
-
session_id: Specific session ID to use (None for auto-generated)
|
|
23
|
-
|
|
24
21
|
Results: AppStartSessionResultSuccess (with session ID) | AppStartSessionResultFailure (session creation error)
|
|
25
22
|
"""
|
|
26
23
|
|
|
27
|
-
# TODO: https://github.com/griptape-ai/griptape-nodes/issues/1600
|
|
28
|
-
session_id: str | None = None
|
|
29
|
-
|
|
30
24
|
|
|
31
25
|
@dataclass
|
|
32
26
|
@PayloadRegistry.register
|
|
File without changes
|
|
@@ -10,7 +10,7 @@ from griptape.events import BaseEvent as GtBaseEvent
|
|
|
10
10
|
from griptape.mixins.serializable_mixin import SerializableMixin
|
|
11
11
|
from griptape.structures import Structure
|
|
12
12
|
from griptape.tools import BaseTool
|
|
13
|
-
from pydantic import BaseModel, Field
|
|
13
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
import builtins
|
|
@@ -118,16 +118,15 @@ class BaseEvent(BaseModel, ABC):
|
|
|
118
118
|
session_id: str | None = Field(default_factory=lambda: BaseEvent._session_id)
|
|
119
119
|
|
|
120
120
|
# Custom JSON encoder for the payload
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
arbitrary_types_allowed = True
|
|
125
|
-
json_encoders: ClassVar[dict] = {
|
|
121
|
+
model_config = ConfigDict(
|
|
122
|
+
arbitrary_types_allowed=True,
|
|
123
|
+
json_encoders={
|
|
126
124
|
# Use to_dict() methods for Griptape objects
|
|
127
125
|
BaseArtifact: lambda obj: obj.to_dict(),
|
|
128
126
|
BaseTool: lambda obj: obj.to_dict(),
|
|
129
127
|
Structure: lambda obj: obj.to_dict(),
|
|
130
|
-
}
|
|
128
|
+
},
|
|
129
|
+
)
|
|
131
130
|
|
|
132
131
|
def dict(self, *args, **kwargs) -> dict[str, Any]:
|
|
133
132
|
"""Override dict to handle payload serialization and add event_type."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -9,7 +9,7 @@ from griptape_nodes.retained_mode.events.base_events import (
|
|
|
9
9
|
WorkflowAlteredMixin,
|
|
10
10
|
WorkflowNotAlteredMixin,
|
|
11
11
|
)
|
|
12
|
-
from griptape_nodes.retained_mode.events.node_events import SerializedNodeCommands
|
|
12
|
+
from griptape_nodes.retained_mode.events.node_events import SerializedNodeCommands, SetLockNodeStateRequest
|
|
13
13
|
from griptape_nodes.retained_mode.events.payload_registry import PayloadRegistry
|
|
14
14
|
from griptape_nodes.retained_mode.events.workflow_events import ImportWorkflowAsReferencedSubFlowRequest
|
|
15
15
|
|
|
@@ -229,6 +229,7 @@ class SerializedFlowCommands:
|
|
|
229
229
|
set_parameter_value_commands: dict[
|
|
230
230
|
SerializedNodeCommands.NodeUUID, list[SerializedNodeCommands.IndirectSetParameterValueCommand]
|
|
231
231
|
]
|
|
232
|
+
set_lock_commands_per_node: dict[SerializedNodeCommands.NodeUUID, SetLockNodeStateRequest]
|
|
232
233
|
sub_flows_commands: list["SerializedFlowCommands"]
|
|
233
234
|
referenced_workflows: set[str]
|
|
234
235
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|