griptape-nodes 0.68.1__py3-none-any.whl → 0.70.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/api_client/client.py +5 -1
- griptape_nodes/app/app.py +51 -0
- griptape_nodes/exe_types/node_groups/base_node_group.py +22 -2
- griptape_nodes/exe_types/node_types.py +1 -1
- griptape_nodes/exe_types/param_components/execution_status_component.py +23 -0
- griptape_nodes/exe_types/param_components/log_parameter.py +5 -1
- griptape_nodes/exe_types/param_components/seed_parameter.py +14 -16
- griptape_nodes/retained_mode/events/node_events.py +38 -3
- griptape_nodes/retained_mode/managers/context_manager.py +1 -27
- griptape_nodes/retained_mode/managers/flow_manager.py +7 -7
- griptape_nodes/retained_mode/managers/node_manager.py +116 -27
- griptape_nodes/retained_mode/managers/object_manager.py +0 -1
- griptape_nodes/retained_mode/retained_mode.py +17 -0
- {griptape_nodes-0.68.1.dist-info → griptape_nodes-0.70.0.dist-info}/METADATA +3 -3
- {griptape_nodes-0.68.1.dist-info → griptape_nodes-0.70.0.dist-info}/RECORD +17 -17
- {griptape_nodes-0.68.1.dist-info → griptape_nodes-0.70.0.dist-info}/WHEEL +2 -2
- {griptape_nodes-0.68.1.dist-info → griptape_nodes-0.70.0.dist-info}/entry_points.txt +0 -0
|
@@ -168,7 +168,11 @@ class Client:
|
|
|
168
168
|
logger.debug("WebSocket client connected")
|
|
169
169
|
except TimeoutError as e:
|
|
170
170
|
logger.error("Failed to connect WebSocket client: timeout")
|
|
171
|
-
msg =
|
|
171
|
+
msg = (
|
|
172
|
+
"Connection timeout - failed to connect to Nodes API. "
|
|
173
|
+
"This usually indicates an invalid or missing GT_CLOUD_API_KEY. "
|
|
174
|
+
"Please verify your API key is correct."
|
|
175
|
+
)
|
|
172
176
|
raise ConnectionError(msg) from e
|
|
173
177
|
|
|
174
178
|
async def _disconnect(self) -> None:
|
griptape_nodes/app/app.py
CHANGED
|
@@ -3,11 +3,14 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
|
+
import sys
|
|
6
7
|
import threading
|
|
7
8
|
from dataclasses import dataclass
|
|
8
9
|
|
|
10
|
+
from rich.align import Align
|
|
9
11
|
from rich.console import Console
|
|
10
12
|
from rich.logging import RichHandler
|
|
13
|
+
from rich.panel import Panel
|
|
11
14
|
|
|
12
15
|
from griptape_nodes.api_client import Client
|
|
13
16
|
from griptape_nodes.retained_mode.events import app_events, execution_events
|
|
@@ -113,6 +116,35 @@ logging.basicConfig(
|
|
|
113
116
|
console = Console()
|
|
114
117
|
|
|
115
118
|
|
|
119
|
+
def _ensure_api_key() -> str:
|
|
120
|
+
"""Verify that GT_CLOUD_API_KEY is set, exit with clear error message if not.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
The API key value
|
|
124
|
+
|
|
125
|
+
Raises:
|
|
126
|
+
SystemExit: If API key is missing or empty
|
|
127
|
+
"""
|
|
128
|
+
secrets_manager = griptape_nodes.SecretsManager()
|
|
129
|
+
api_key = secrets_manager.get_secret("GT_CLOUD_API_KEY", should_error_on_not_found=False)
|
|
130
|
+
|
|
131
|
+
if not api_key:
|
|
132
|
+
message = Panel(
|
|
133
|
+
Align.center(
|
|
134
|
+
"[bold red]Nodes API key is not set, please run [code]gtn init[/code] with a valid key:[/bold red]\n"
|
|
135
|
+
"[code]gtn init --api-key <your key>[/code]\n\n"
|
|
136
|
+
"[bold red]You can generate a new key from [/bold red][bold blue][link=https://nodes.griptape.ai]https://nodes.griptape.ai[/link][/bold blue]",
|
|
137
|
+
),
|
|
138
|
+
title="[red]X[/red] Missing Nodes API Key",
|
|
139
|
+
border_style="red",
|
|
140
|
+
padding=(1, 4),
|
|
141
|
+
)
|
|
142
|
+
console.print(message)
|
|
143
|
+
sys.exit(1)
|
|
144
|
+
|
|
145
|
+
return api_key
|
|
146
|
+
|
|
147
|
+
|
|
116
148
|
def start_app() -> None:
|
|
117
149
|
"""Legacy sync entry point - runs async app."""
|
|
118
150
|
try:
|
|
@@ -125,6 +157,9 @@ def start_app() -> None:
|
|
|
125
157
|
|
|
126
158
|
async def astart_app() -> None:
|
|
127
159
|
"""New async app entry point."""
|
|
160
|
+
# Verify API key is set before starting
|
|
161
|
+
_ensure_api_key()
|
|
162
|
+
|
|
128
163
|
# Initialize event queue in main thread
|
|
129
164
|
griptape_nodes.EventManager().initialize_queue()
|
|
130
165
|
|
|
@@ -154,6 +189,22 @@ def _start_websocket_connection() -> None:
|
|
|
154
189
|
|
|
155
190
|
# Run the async WebSocket tasks
|
|
156
191
|
loop.run_until_complete(_run_websocket_tasks())
|
|
192
|
+
except ConnectionError:
|
|
193
|
+
# Connection failed - likely due to invalid/missing API key
|
|
194
|
+
message = Panel(
|
|
195
|
+
Align.center(
|
|
196
|
+
"[bold red]Failed to connect to Nodes API.[/bold red]\n\n"
|
|
197
|
+
"This usually indicates an invalid or missing [code]GT_CLOUD_API_KEY[/code].\n\n"
|
|
198
|
+
"[bold red]Please verify your API key:[/bold red]\n"
|
|
199
|
+
"[code]gtn init --api-key <your key>[/code]\n\n"
|
|
200
|
+
"[bold red]You can generate a new key from [/bold red][bold blue][link=https://nodes.griptape.ai]https://nodes.griptape.ai[/link][/bold blue]",
|
|
201
|
+
),
|
|
202
|
+
title="[red]X[/red] Connection Failed",
|
|
203
|
+
border_style="red",
|
|
204
|
+
padding=(1, 4),
|
|
205
|
+
)
|
|
206
|
+
console.print(message)
|
|
207
|
+
sys.exit(1)
|
|
157
208
|
except Exception as e:
|
|
158
209
|
logger.error("WebSocket thread error: %s", e)
|
|
159
210
|
raise
|
|
@@ -65,8 +65,7 @@ class BaseNodeGroup(BaseNode):
|
|
|
65
65
|
Args:
|
|
66
66
|
nodes: A list of nodes to add to this group
|
|
67
67
|
"""
|
|
68
|
-
|
|
69
|
-
self.nodes[node.name] = node
|
|
68
|
+
self._add_nodes_to_group_dict(nodes)
|
|
70
69
|
|
|
71
70
|
node_names_in_group = set(self.nodes.keys())
|
|
72
71
|
self.metadata["node_names_in_group"] = list(node_names_in_group)
|
|
@@ -93,3 +92,24 @@ class BaseNodeGroup(BaseNode):
|
|
|
93
92
|
if node.name not in self.nodes:
|
|
94
93
|
msg = f"Node {node.name} is not in node group {self.name}"
|
|
95
94
|
raise ValueError(msg)
|
|
95
|
+
|
|
96
|
+
def handle_child_node_rename(self, old_name: str, new_name: str) -> None:
|
|
97
|
+
"""Update group membership when a child node is renamed.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
old_name: The old name of the child node
|
|
101
|
+
new_name: The new name of the child node
|
|
102
|
+
"""
|
|
103
|
+
if old_name not in self.nodes:
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
# Update the nodes dictionary
|
|
107
|
+
node = self.nodes.pop(old_name)
|
|
108
|
+
self.nodes[new_name] = node
|
|
109
|
+
|
|
110
|
+
# Update the metadata
|
|
111
|
+
node_names_in_group = self.metadata.get("node_names_in_group", [])
|
|
112
|
+
if old_name in node_names_in_group:
|
|
113
|
+
node_names_in_group.remove(old_name)
|
|
114
|
+
node_names_in_group.append(new_name)
|
|
115
|
+
self.metadata["node_names_in_group"] = node_names_in_group
|
|
@@ -1623,7 +1623,7 @@ class EndNode(BaseNode):
|
|
|
1623
1623
|
self,
|
|
1624
1624
|
was_successful_modes={ParameterMode.PROPERTY},
|
|
1625
1625
|
result_details_modes={ParameterMode.INPUT},
|
|
1626
|
-
parameter_group_initially_collapsed=
|
|
1626
|
+
parameter_group_initially_collapsed=True,
|
|
1627
1627
|
result_details_placeholder="Details about the completion or failure will be shown here.",
|
|
1628
1628
|
)
|
|
1629
1629
|
|
|
@@ -83,6 +83,17 @@ class ExecutionStatusComponent:
|
|
|
83
83
|
"""
|
|
84
84
|
return self._status_group
|
|
85
85
|
|
|
86
|
+
def _update_status_group_display_label(self, *, show_warning: bool) -> None:
|
|
87
|
+
"""Update the Status ParameterGroup display label with optional warning emoji."""
|
|
88
|
+
if show_warning:
|
|
89
|
+
self._status_group.update_ui_options_key("display_name", "⚠️ Status")
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
# Remove display_name to use default "Status" from name
|
|
93
|
+
ui_options = self._status_group.ui_options.copy()
|
|
94
|
+
ui_options.pop("display_name", None)
|
|
95
|
+
self._status_group.ui_options = ui_options
|
|
96
|
+
|
|
86
97
|
def set_execution_result(self, *, was_successful: bool, result_details: str) -> None:
|
|
87
98
|
"""Set the execution result values.
|
|
88
99
|
|
|
@@ -92,6 +103,16 @@ class ExecutionStatusComponent:
|
|
|
92
103
|
"""
|
|
93
104
|
self._update_parameter_value(self._was_successful, was_successful)
|
|
94
105
|
self._update_parameter_value(self._result_details, result_details)
|
|
106
|
+
# Update display label: show warning emoji only on actual failure (not placeholder/initialization messages)
|
|
107
|
+
# While string matching is not the best practice, it's currently the only way to check for placeholder messages.
|
|
108
|
+
# TODO: use a better approach to check for placeholder messages. https://github.com/griptape-ai/griptape-nodes/issues/3686
|
|
109
|
+
is_placeholder = result_details in (
|
|
110
|
+
"<Results will appear when the node executes>",
|
|
111
|
+
"Beginning execution...",
|
|
112
|
+
"",
|
|
113
|
+
)
|
|
114
|
+
show_warning = not was_successful and not is_placeholder
|
|
115
|
+
self._update_status_group_display_label(show_warning=show_warning)
|
|
95
116
|
|
|
96
117
|
def clear_execution_status(self, initial_message: str | None = None) -> None:
|
|
97
118
|
"""Clear execution status and reset parameters.
|
|
@@ -102,6 +123,8 @@ class ExecutionStatusComponent:
|
|
|
102
123
|
if initial_message is None:
|
|
103
124
|
initial_message = ""
|
|
104
125
|
self.set_execution_result(was_successful=False, result_details=initial_message)
|
|
126
|
+
# Reset to "Status" during execution (not a failure yet)
|
|
127
|
+
self._update_status_group_display_label(show_warning=False)
|
|
105
128
|
|
|
106
129
|
def append_to_result_details(self, additional_text: str, separator: str = "\n") -> None:
|
|
107
130
|
"""Append text to the existing result_details.
|
|
@@ -20,7 +20,7 @@ class LogParameter:
|
|
|
20
20
|
output_type="str",
|
|
21
21
|
allowed_modes={ParameterMode.OUTPUT},
|
|
22
22
|
tooltip="logs",
|
|
23
|
-
ui_options={"multiline": True},
|
|
23
|
+
ui_options={"multiline": True, "placeholder_text": ""},
|
|
24
24
|
)
|
|
25
25
|
)
|
|
26
26
|
|
|
@@ -68,6 +68,10 @@ class StdoutCapture:
|
|
|
68
68
|
def flush(self) -> None:
|
|
69
69
|
self._original_stdout.flush()
|
|
70
70
|
|
|
71
|
+
def isatty(self) -> bool:
|
|
72
|
+
# Return False to prevent libraries from outputting ANSI color codes
|
|
73
|
+
return False
|
|
74
|
+
|
|
71
75
|
def __enter__(self) -> "StdoutCapture":
|
|
72
76
|
sys.stdout = self
|
|
73
77
|
return self
|
|
@@ -3,6 +3,8 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from griptape_nodes.exe_types.core_types import Parameter, ParameterMode
|
|
5
5
|
from griptape_nodes.exe_types.node_types import BaseNode
|
|
6
|
+
from griptape_nodes.exe_types.param_types.parameter_bool import ParameterBool
|
|
7
|
+
from griptape_nodes.exe_types.param_types.parameter_int import ParameterInt
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class SeedParameter:
|
|
@@ -10,24 +12,20 @@ class SeedParameter:
|
|
|
10
12
|
self._node = node
|
|
11
13
|
self._max_seed = max_seed
|
|
12
14
|
|
|
13
|
-
def add_input_parameters(self) -> None:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
output_type="bool",
|
|
19
|
-
tooltip="randomize the seed on each run",
|
|
20
|
-
default_value=False,
|
|
21
|
-
)
|
|
15
|
+
def add_input_parameters(self, *, inside_param_group: bool = False) -> None:
|
|
16
|
+
randomize_seed_parameter = ParameterBool(
|
|
17
|
+
name="randomize_seed",
|
|
18
|
+
tooltip="randomize the seed on each run",
|
|
19
|
+
default_value=False,
|
|
22
20
|
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
tooltip="seed",
|
|
28
|
-
default_value=42,
|
|
29
|
-
)
|
|
21
|
+
seed_parameter = ParameterInt(
|
|
22
|
+
name="seed",
|
|
23
|
+
tooltip="the seed to use for the generation",
|
|
24
|
+
default_value=42,
|
|
30
25
|
)
|
|
26
|
+
if not inside_param_group:
|
|
27
|
+
self._node.add_parameter(randomize_seed_parameter)
|
|
28
|
+
self._node.add_parameter(seed_parameter)
|
|
31
29
|
|
|
32
30
|
def remove_input_parameters(self) -> None:
|
|
33
31
|
self._node.remove_parameter_element_by_name("randomize_seed")
|
|
@@ -390,8 +390,6 @@ class GetAllNodeInfoResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailure)
|
|
|
390
390
|
class SetLockNodeStateRequest(WorkflowNotAlteredMixin, RequestPayload):
|
|
391
391
|
"""Lock a node.
|
|
392
392
|
|
|
393
|
-
Use when: Implementing locking functionality, preventing changes to nodes.
|
|
394
|
-
|
|
395
393
|
Args:
|
|
396
394
|
node_name: Name of the node to lock
|
|
397
395
|
lock: Whether to lock or unlock the node. If true, the node will be locked, otherwise it will be unlocked.
|
|
@@ -418,6 +416,39 @@ class SetLockNodeStateResultFailure(WorkflowNotAlteredMixin, ResultPayloadFailur
|
|
|
418
416
|
"""Node failed to lock."""
|
|
419
417
|
|
|
420
418
|
|
|
419
|
+
@dataclass
|
|
420
|
+
@PayloadRegistry.register
|
|
421
|
+
class BatchSetNodeLockStateRequest(WorkflowNotAlteredMixin, RequestPayload):
|
|
422
|
+
"""Set lock state for multiple nodes in a single request.
|
|
423
|
+
|
|
424
|
+
Use when: Locking or unlocking multiple nodes at once, consistent with BatchSetNodeMetadataRequest.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
node_names: Names of nodes to lock/unlock.
|
|
428
|
+
lock: Whether to lock (True) or unlock (False) the nodes.
|
|
429
|
+
|
|
430
|
+
Results: BatchSetNodeLockStateResultSuccess | BatchSetNodeLockStateResultFailure
|
|
431
|
+
"""
|
|
432
|
+
|
|
433
|
+
node_names: list[str]
|
|
434
|
+
lock: bool
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
@dataclass
|
|
438
|
+
@PayloadRegistry.register
|
|
439
|
+
class BatchSetNodeLockStateResultSuccess(WorkflowNotAlteredMixin, ResultPayloadSuccess):
|
|
440
|
+
"""Batch node lock state update completed successfully."""
|
|
441
|
+
|
|
442
|
+
updated_nodes: list[str]
|
|
443
|
+
failed_nodes: dict[str, str] = field(default_factory=dict)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
@dataclass
|
|
447
|
+
@PayloadRegistry.register
|
|
448
|
+
class BatchSetNodeLockStateResultFailure(ResultPayloadFailure):
|
|
449
|
+
"""Batch node lock state update failed. Common causes: all nodes not found."""
|
|
450
|
+
|
|
451
|
+
|
|
421
452
|
# A Node's state can be serialized to a sequence of commands that the engine runs.
|
|
422
453
|
@dataclass
|
|
423
454
|
class SerializedNodeCommands:
|
|
@@ -533,6 +564,7 @@ class SerializeNodeToCommandsRequest(RequestPayload):
|
|
|
533
564
|
serialized_parameter_value_tracker: SerializedParameterValueTracker = field(
|
|
534
565
|
default_factory=SerializedParameterValueTracker
|
|
535
566
|
)
|
|
567
|
+
use_pickling: bool = False
|
|
536
568
|
|
|
537
569
|
|
|
538
570
|
@dataclass
|
|
@@ -617,7 +649,8 @@ class SerializeSelectedNodesToCommandsResultSuccess(WorkflowNotAlteredMixin, Res
|
|
|
617
649
|
|
|
618
650
|
# They will be passed with node_name, timestamp
|
|
619
651
|
# Could be a flow command if it's all nodes in a flow.
|
|
620
|
-
serialized_selected_node_commands:
|
|
652
|
+
serialized_selected_node_commands: str
|
|
653
|
+
pickled_values: dict[str, str]
|
|
621
654
|
|
|
622
655
|
|
|
623
656
|
@dataclass
|
|
@@ -643,6 +676,8 @@ class DeserializeSelectedNodesFromCommandsRequest(WorkflowNotAlteredMixin, Reque
|
|
|
643
676
|
Results: DeserializeSelectedNodesFromCommandsResultSuccess (with node names) | DeserializeSelectedNodesFromCommandsResultFailure (deserialization error)
|
|
644
677
|
"""
|
|
645
678
|
|
|
679
|
+
deserialize_commands: str
|
|
680
|
+
pickled_values: dict[str, str]
|
|
646
681
|
positions: list[NewPosition] | None = None
|
|
647
682
|
|
|
648
683
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
6
|
from griptape_nodes.exe_types.flow import ControlFlow
|
|
7
7
|
from griptape_nodes.retained_mode.events.context_events import (
|
|
@@ -18,8 +18,6 @@ if TYPE_CHECKING:
|
|
|
18
18
|
from griptape_nodes.exe_types.core_types import BaseNodeElement
|
|
19
19
|
from griptape_nodes.exe_types.node_types import BaseNode
|
|
20
20
|
from griptape_nodes.retained_mode.events.base_events import ResultPayload
|
|
21
|
-
from griptape_nodes.retained_mode.events.flow_events import SerializedFlowCommands
|
|
22
|
-
from griptape_nodes.retained_mode.events.node_events import SerializedSelectedNodesCommands
|
|
23
21
|
from griptape_nodes.retained_mode.managers.event_manager import EventManager
|
|
24
22
|
|
|
25
23
|
logger = logging.getLogger("griptape_nodes")
|
|
@@ -34,7 +32,6 @@ class ContextManager:
|
|
|
34
32
|
"""
|
|
35
33
|
|
|
36
34
|
_workflow_stack: list[ContextManager.WorkflowContextState]
|
|
37
|
-
_clipboard: ClipBoard
|
|
38
35
|
|
|
39
36
|
class WorkflowContextError(Exception):
|
|
40
37
|
"""Base exception for workflow context errors."""
|
|
@@ -242,32 +239,9 @@ class ContextManager:
|
|
|
242
239
|
) -> None:
|
|
243
240
|
self._manager.pop_element()
|
|
244
241
|
|
|
245
|
-
class ClipBoard:
|
|
246
|
-
"""Keeps Commands for Copying or Pasting."""
|
|
247
|
-
|
|
248
|
-
# Contains flow, node, parameter, connections
|
|
249
|
-
flow_commands: SerializedFlowCommands | None
|
|
250
|
-
# Contains node and Parameter and relevant connections
|
|
251
|
-
node_commands: SerializedSelectedNodesCommands | None
|
|
252
|
-
parameter_uuid_to_values: dict[str, Any] | None
|
|
253
|
-
|
|
254
|
-
def __init__(self) -> None:
|
|
255
|
-
self.flow_commands = None
|
|
256
|
-
self.node_commands = None
|
|
257
|
-
self.parameter_uuid_to_values = None
|
|
258
|
-
|
|
259
|
-
def clear(self) -> None:
|
|
260
|
-
del self.flow_commands
|
|
261
|
-
self.flow_commands = None
|
|
262
|
-
del self.node_commands
|
|
263
|
-
self.node_commands = None
|
|
264
|
-
if self.parameter_uuid_to_values is not None:
|
|
265
|
-
self.parameter_uuid_to_values.clear()
|
|
266
|
-
|
|
267
242
|
def __init__(self, event_manager: EventManager) -> None:
|
|
268
243
|
"""Initialize the context manager with empty workflow and flow stacks."""
|
|
269
244
|
self._workflow_stack = []
|
|
270
|
-
self._clipboard = self.ClipBoard()
|
|
271
245
|
event_manager.assign_manager_to_request_type(
|
|
272
246
|
request_type=SetWorkflowContextRequest, callback=self.on_set_workflow_context_request
|
|
273
247
|
)
|
|
@@ -17,7 +17,7 @@ from griptape_nodes.exe_types.core_types import (
|
|
|
17
17
|
ParameterTypeBuiltin,
|
|
18
18
|
)
|
|
19
19
|
from griptape_nodes.exe_types.flow import ControlFlow
|
|
20
|
-
from griptape_nodes.exe_types.node_groups import SubflowNodeGroup
|
|
20
|
+
from griptape_nodes.exe_types.node_groups import BaseNodeGroup, SubflowNodeGroup
|
|
21
21
|
from griptape_nodes.exe_types.node_types import (
|
|
22
22
|
BaseNode,
|
|
23
23
|
ErrorProxyNode,
|
|
@@ -1530,9 +1530,9 @@ class FlowManager:
|
|
|
1530
1530
|
if node_name is not None:
|
|
1531
1531
|
node_name_to_uuid[node_name] = serialize_result.serialized_node_commands.node_uuid
|
|
1532
1532
|
|
|
1533
|
-
#
|
|
1533
|
+
# BaseNodeGroups must be serialized LAST because they reference child node names via node_names_to_add
|
|
1534
1534
|
# If we deserialize a NodeGroup before its children, the child nodes won't exist yet
|
|
1535
|
-
if isinstance(node,
|
|
1535
|
+
if isinstance(node, BaseNodeGroup):
|
|
1536
1536
|
serialized_node_group_commands.append(serialize_result.serialized_node_commands)
|
|
1537
1537
|
else:
|
|
1538
1538
|
serialized_node_commands.append(serialize_result.serialized_node_commands)
|
|
@@ -1543,7 +1543,7 @@ class FlowManager:
|
|
|
1543
1543
|
serialize_result.set_parameter_value_commands
|
|
1544
1544
|
)
|
|
1545
1545
|
|
|
1546
|
-
# Update
|
|
1546
|
+
# Update BaseNodeGroup commands to use UUIDs instead of names in node_names_to_add
|
|
1547
1547
|
# This allows workflow generation to directly look up variable names from UUIDs
|
|
1548
1548
|
|
|
1549
1549
|
for node_group_command in serialized_node_group_commands:
|
|
@@ -3224,9 +3224,9 @@ class FlowManager:
|
|
|
3224
3224
|
# Store the serialized node's UUID for correlation to connections and setting parameter values later.
|
|
3225
3225
|
node_name_to_uuid[node_name] = serialized_node.node_uuid
|
|
3226
3226
|
|
|
3227
|
-
#
|
|
3227
|
+
# BaseNodeGroups must be serialized LAST because CreateNodeGroupRequest references child node names
|
|
3228
3228
|
# If we deserialize a NodeGroup before its children, the child nodes won't exist yet
|
|
3229
|
-
if isinstance(node,
|
|
3229
|
+
if isinstance(node, BaseNodeGroup):
|
|
3230
3230
|
serialized_node_group_commands.append(serialized_node)
|
|
3231
3231
|
else:
|
|
3232
3232
|
serialized_node_commands.append(serialized_node)
|
|
@@ -3299,7 +3299,7 @@ class FlowManager:
|
|
|
3299
3299
|
# This ensures child nodes exist before their parent NodeGroups are created during deserialization
|
|
3300
3300
|
serialized_node_commands.extend(serialized_node_group_commands)
|
|
3301
3301
|
|
|
3302
|
-
# Update
|
|
3302
|
+
# Update BaseNodeGroup commands to use UUIDs instead of names in node_names_to_add
|
|
3303
3303
|
# This allows workflow generation to directly look up variable names from UUIDs
|
|
3304
3304
|
# Build a complete node name to UUID map including nodes from all subflows
|
|
3305
3305
|
complete_node_name_to_uuid = dict(node_name_to_uuid) # Start with current flow's nodes
|
|
@@ -70,6 +70,9 @@ from griptape_nodes.retained_mode.events.node_events import (
|
|
|
70
70
|
AddNodesToNodeGroupRequest,
|
|
71
71
|
AddNodesToNodeGroupResultFailure,
|
|
72
72
|
AddNodesToNodeGroupResultSuccess,
|
|
73
|
+
BatchSetNodeLockStateRequest,
|
|
74
|
+
BatchSetNodeLockStateResultFailure,
|
|
75
|
+
BatchSetNodeLockStateResultSuccess,
|
|
73
76
|
BatchSetNodeMetadataRequest,
|
|
74
77
|
BatchSetNodeMetadataResultFailure,
|
|
75
78
|
BatchSetNodeMetadataResultSuccess,
|
|
@@ -292,6 +295,9 @@ class NodeManager:
|
|
|
292
295
|
CanResetNodeToDefaultsRequest, self.on_can_reset_node_to_defaults_request
|
|
293
296
|
)
|
|
294
297
|
event_manager.assign_manager_to_request_type(ResetNodeToDefaultsRequest, self.on_reset_node_to_defaults_request)
|
|
298
|
+
event_manager.assign_manager_to_request_type(
|
|
299
|
+
BatchSetNodeLockStateRequest, self.on_batch_set_lock_node_state_request
|
|
300
|
+
)
|
|
295
301
|
|
|
296
302
|
def handle_node_rename(self, old_name: str, new_name: str) -> None:
|
|
297
303
|
# Get the node itself
|
|
@@ -317,6 +323,12 @@ class NodeManager:
|
|
|
317
323
|
connection.source_node.name = new_name
|
|
318
324
|
temp = connections.outgoing_index.pop(old_name)
|
|
319
325
|
connections.outgoing_index[new_name] = temp
|
|
326
|
+
|
|
327
|
+
# Update parent group membership if node belongs to a group
|
|
328
|
+
parent_group = node.parent_group
|
|
329
|
+
if parent_group is not None and isinstance(parent_group, BaseNodeGroup):
|
|
330
|
+
parent_group.handle_child_node_rename(old_name, new_name)
|
|
331
|
+
|
|
320
332
|
# update the node in the flow!
|
|
321
333
|
flow.remove_node(old_name)
|
|
322
334
|
node.name = new_name
|
|
@@ -2631,9 +2643,8 @@ class NodeManager:
|
|
|
2631
2643
|
library_version = library_metadata_result.metadata.library_version
|
|
2632
2644
|
library_details = LibraryNameAndVersion(library_name=library_used, library_version=library_version)
|
|
2633
2645
|
|
|
2634
|
-
# Handle
|
|
2635
|
-
if isinstance(node,
|
|
2636
|
-
# For non-SubflowNodeGroup, library_details should always be set
|
|
2646
|
+
# Handle BaseNodeGroup specially - serialize like normal nodes but preserve node group behavior
|
|
2647
|
+
if isinstance(node, BaseNodeGroup):
|
|
2637
2648
|
if library_details is None:
|
|
2638
2649
|
details = f"Attempted to serialize Node '{node_name}' to commands. Library details missing."
|
|
2639
2650
|
return SerializeNodeToCommandsResultFailure(result_details=details)
|
|
@@ -2651,7 +2662,6 @@ class NodeManager:
|
|
|
2651
2662
|
metadata=metadata_copy,
|
|
2652
2663
|
)
|
|
2653
2664
|
else:
|
|
2654
|
-
# For non-SubflowNodeGroup, library_details should always be set
|
|
2655
2665
|
if library_details is None:
|
|
2656
2666
|
details = f"Attempted to serialize Node '{node_name}' to commands. Library details missing."
|
|
2657
2667
|
return SerializeNodeToCommandsResultFailure(result_details=details)
|
|
@@ -2771,6 +2781,7 @@ class NodeManager:
|
|
|
2771
2781
|
unique_parameter_uuid_to_values=request.unique_parameter_uuid_to_values,
|
|
2772
2782
|
serialized_parameter_value_tracker=request.serialized_parameter_value_tracker,
|
|
2773
2783
|
create_node_request=create_node_request,
|
|
2784
|
+
use_pickling=request.use_pickling,
|
|
2774
2785
|
)
|
|
2775
2786
|
if set_param_value_requests is not None:
|
|
2776
2787
|
set_value_commands.extend(set_param_value_requests)
|
|
@@ -2973,6 +2984,7 @@ class NodeManager:
|
|
|
2973
2984
|
node_name=node_name,
|
|
2974
2985
|
unique_parameter_uuid_to_values=unique_uuid_to_values,
|
|
2975
2986
|
serialized_parameter_value_tracker=serialized_parameter_value_tracker,
|
|
2987
|
+
use_pickling=True,
|
|
2976
2988
|
)
|
|
2977
2989
|
)
|
|
2978
2990
|
if not isinstance(result, SerializeNodeToCommandsResultSuccess):
|
|
@@ -3019,22 +3031,55 @@ class NodeManager:
|
|
|
3019
3031
|
set_parameter_value_commands=parameter_commands,
|
|
3020
3032
|
set_lock_commands_per_node=lock_commands,
|
|
3021
3033
|
)
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3034
|
+
|
|
3035
|
+
# Encode pickled bytes to latin-1 strings for JSON serialization
|
|
3036
|
+
encoded_values = {}
|
|
3037
|
+
for uuid, value in unique_uuid_to_values.items():
|
|
3038
|
+
if isinstance(value, bytes):
|
|
3039
|
+
# Pickled bytes - encode as latin-1 string for transport
|
|
3040
|
+
encoded_values[uuid] = value.decode("latin1")
|
|
3041
|
+
else:
|
|
3042
|
+
# Non-pickled value - keep as-is (for backward compatibility)
|
|
3043
|
+
encoded_values[uuid] = value
|
|
3044
|
+
|
|
3045
|
+
# Pickle the commands object and encode as latin-1 string for transport
|
|
3046
|
+
pickled_commands_bytes = pickle.dumps(final_result)
|
|
3047
|
+
pickled_commands_string = pickled_commands_bytes.decode("latin1")
|
|
3026
3048
|
return SerializeSelectedNodesToCommandsResultSuccess(
|
|
3027
|
-
|
|
3049
|
+
pickled_commands_string, # Send pickled string instead of object
|
|
3050
|
+
pickled_values=encoded_values,
|
|
3028
3051
|
result_details=f"Successfully serialized {len(request.nodes_to_serialize)} selected nodes to commands.",
|
|
3029
3052
|
)
|
|
3030
3053
|
|
|
3031
|
-
def on_deserialize_selected_nodes_from_commands( # noqa: C901, PLR0912
|
|
3054
|
+
def on_deserialize_selected_nodes_from_commands( # noqa: C901, PLR0912, PLR0915
|
|
3032
3055
|
self,
|
|
3033
3056
|
request: DeserializeSelectedNodesFromCommandsRequest,
|
|
3034
3057
|
) -> ResultPayload:
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3058
|
+
# Decode latin-1 encoded pickled strings back to Python objects
|
|
3059
|
+
decoded_values = {}
|
|
3060
|
+
if request.pickled_values:
|
|
3061
|
+
for uuid, latin1_string in request.pickled_values.items():
|
|
3062
|
+
if isinstance(latin1_string, str):
|
|
3063
|
+
try:
|
|
3064
|
+
# Decode: latin-1 string → bytes → unpickled object
|
|
3065
|
+
pickled_bytes = latin1_string.encode("latin1")
|
|
3066
|
+
decoded_values[uuid] = pickle.loads(pickled_bytes) # noqa: S301 Expecting this from the GUI.
|
|
3067
|
+
except Exception:
|
|
3068
|
+
details = f"Failed to unpickle parameter value for UUID {uuid}"
|
|
3069
|
+
logger.warning(details)
|
|
3070
|
+
# Keep original value if unpickling fails
|
|
3071
|
+
decoded_values[uuid] = latin1_string
|
|
3072
|
+
else:
|
|
3073
|
+
# Not a string, keep as-is
|
|
3074
|
+
decoded_values[uuid] = latin1_string
|
|
3075
|
+
|
|
3076
|
+
# Unpickle the commands string into SerializedSelectedNodesCommands
|
|
3077
|
+
try:
|
|
3078
|
+
pickled_commands_bytes = request.deserialize_commands.encode("latin1")
|
|
3079
|
+
commands = pickle.loads(pickled_commands_bytes) # noqa: S301 Expecting this from the GUI.
|
|
3080
|
+
except Exception as e:
|
|
3081
|
+
details = f"Failed to unpickle commands: {e}"
|
|
3082
|
+
return DeserializeSelectedNodesFromCommandsResultFailure(result_details=details)
|
|
3038
3083
|
connections = commands.serialized_connection_commands
|
|
3039
3084
|
node_uuid_to_name = {}
|
|
3040
3085
|
# Enumerate because positions is in the same order as the node commands.
|
|
@@ -3068,10 +3113,9 @@ class NodeManager:
|
|
|
3068
3113
|
param_request = parameter_command.set_parameter_value_command
|
|
3069
3114
|
# Set the Node name
|
|
3070
3115
|
param_request.node_name = result.node_name
|
|
3071
|
-
# Set the new value
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
value = table[parameter_command.unique_value_uuid]
|
|
3116
|
+
# Set the new value from decoded_values
|
|
3117
|
+
if decoded_values and parameter_command.unique_value_uuid in decoded_values:
|
|
3118
|
+
value = decoded_values[parameter_command.unique_value_uuid]
|
|
3075
3119
|
# Using try-except-pass instead of contextlib.suppress because it's clearer.
|
|
3076
3120
|
try: # noqa: SIM105
|
|
3077
3121
|
# If we're pasting multiple times - we need to create a new copy for each paste so they don't all have the same reference.
|
|
@@ -3109,13 +3153,20 @@ class NodeManager:
|
|
|
3109
3153
|
)
|
|
3110
3154
|
|
|
3111
3155
|
def on_duplicate_selected_nodes(self, request: DuplicateSelectedNodesRequest) -> ResultPayload:
|
|
3112
|
-
|
|
3156
|
+
serialize_result = GriptapeNodes.handle_request(
|
|
3113
3157
|
SerializeSelectedNodesToCommandsRequest(nodes_to_serialize=request.nodes_to_duplicate)
|
|
3114
3158
|
)
|
|
3115
|
-
if
|
|
3159
|
+
if not isinstance(serialize_result, SerializeSelectedNodesToCommandsResultSuccess):
|
|
3116
3160
|
details = "Failed to serialized selected nodes."
|
|
3117
3161
|
return DuplicateSelectedNodesResultFailure(result_details=details)
|
|
3118
|
-
|
|
3162
|
+
|
|
3163
|
+
# Pass the pickled commands and values to deserialization
|
|
3164
|
+
deserialize_request = DeserializeSelectedNodesFromCommandsRequest(
|
|
3165
|
+
deserialize_commands=serialize_result.serialized_selected_node_commands,
|
|
3166
|
+
pickled_values=serialize_result.pickled_values,
|
|
3167
|
+
positions=request.positions,
|
|
3168
|
+
)
|
|
3169
|
+
result = GriptapeNodes.handle_request(deserialize_request)
|
|
3119
3170
|
if not isinstance(result, DeserializeSelectedNodesFromCommandsResultSuccess):
|
|
3120
3171
|
details = "Failed to deserialize selected nodes."
|
|
3121
3172
|
return DuplicateSelectedNodesResultFailure(result_details=details)
|
|
@@ -3167,6 +3218,7 @@ class NodeManager:
|
|
|
3167
3218
|
node_name: str,
|
|
3168
3219
|
*,
|
|
3169
3220
|
is_output: bool,
|
|
3221
|
+
use_pickling: bool = False,
|
|
3170
3222
|
) -> SerializedNodeCommands.IndirectSetParameterValueCommand | None:
|
|
3171
3223
|
try:
|
|
3172
3224
|
hash(value)
|
|
@@ -3201,12 +3253,20 @@ class NodeManager:
|
|
|
3201
3253
|
return None
|
|
3202
3254
|
# The value should be serialized. Add it to the map of uniques.
|
|
3203
3255
|
unique_uuid = SerializedNodeCommands.UniqueParameterValueUUID(str(uuid4()))
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
unique_parameter_uuid_to_values[unique_uuid] =
|
|
3256
|
+
|
|
3257
|
+
if use_pickling:
|
|
3258
|
+
# Use pickle serialization via WorkflowManager
|
|
3259
|
+
workflow_manager = GriptapeNodes.WorkflowManager()
|
|
3260
|
+
pickled_bytes = workflow_manager._patch_and_pickle_object(value)
|
|
3261
|
+
unique_parameter_uuid_to_values[unique_uuid] = pickled_bytes
|
|
3262
|
+
else:
|
|
3263
|
+
# Use existing deep copy approach
|
|
3264
|
+
try:
|
|
3265
|
+
unique_parameter_uuid_to_values[unique_uuid] = copy.deepcopy(value)
|
|
3266
|
+
except Exception:
|
|
3267
|
+
details = f"Attempted to serialize parameter '{parameter_name}` on node '{node_name}'. The parameter value could not be copied. It will be serialized by value. If problems arise from this, ensure the type '{type(value)}' works with copy.deepcopy()."
|
|
3268
|
+
logger.warning(details)
|
|
3269
|
+
unique_parameter_uuid_to_values[unique_uuid] = value
|
|
3210
3270
|
serialized_parameter_value_tracker.add_as_serializable(value_id, unique_uuid)
|
|
3211
3271
|
|
|
3212
3272
|
# Serialize it
|
|
@@ -3223,12 +3283,14 @@ class NodeManager:
|
|
|
3223
3283
|
return indirect_set_value_command
|
|
3224
3284
|
|
|
3225
3285
|
@staticmethod
|
|
3226
|
-
def handle_parameter_value_saving(
|
|
3286
|
+
def handle_parameter_value_saving( # noqa: PLR0913
|
|
3227
3287
|
parameter: Parameter,
|
|
3228
3288
|
node: BaseNode,
|
|
3229
3289
|
unique_parameter_uuid_to_values: dict[SerializedNodeCommands.UniqueParameterValueUUID, Any],
|
|
3230
3290
|
serialized_parameter_value_tracker: SerializedParameterValueTracker,
|
|
3231
3291
|
create_node_request: CreateNodeRequest,
|
|
3292
|
+
*,
|
|
3293
|
+
use_pickling: bool = False,
|
|
3232
3294
|
) -> list[SerializedNodeCommands.IndirectSetParameterValueCommand] | None:
|
|
3233
3295
|
"""Generates code to save a parameter value for a node in a Griptape workflow.
|
|
3234
3296
|
|
|
@@ -3246,6 +3308,7 @@ class NodeManager:
|
|
|
3246
3308
|
unique_parameter_uuid_to_values (dict[SerializedNodeCommands.UniqueParameterValueUUID, Any]): Dictionary mapping unique value UUIDs to values
|
|
3247
3309
|
serialized_parameter_value_tracker (SerializedParameterValueTracker): Object mapping maintaining value hashes to unique value UUIDs, and non-serializable values
|
|
3248
3310
|
create_node_request (CreateNodeRequest): The node creation request that will be modified if serialization fails
|
|
3311
|
+
use_pickling (bool): If True, use pickle-based serialization; if False, use deep copy
|
|
3249
3312
|
|
|
3250
3313
|
Returns:
|
|
3251
3314
|
None (if no value to be serialized) or an IndirectSetParameterValueCommand linking the value to the unique value map
|
|
@@ -3282,6 +3345,7 @@ class NodeManager:
|
|
|
3282
3345
|
is_output=False,
|
|
3283
3346
|
parameter_name=parameter.name,
|
|
3284
3347
|
node_name=node.name,
|
|
3348
|
+
use_pickling=use_pickling,
|
|
3285
3349
|
)
|
|
3286
3350
|
if internal_command is None:
|
|
3287
3351
|
details = f"Attempted to serialize set value for parameter '{parameter.name}' on node '{node.name}'. The set value will not be restored in anything that attempts to deserialize or save this node. The value for this parameter was not serialized because it did not match Griptape Nodes' criteria for serializability. To remedy, either update the value's type to support serializability or mark the parameter as not serializable by setting serializable=False when creating the parameter."
|
|
@@ -3300,6 +3364,7 @@ class NodeManager:
|
|
|
3300
3364
|
is_output=True,
|
|
3301
3365
|
parameter_name=parameter.name,
|
|
3302
3366
|
node_name=node.name,
|
|
3367
|
+
use_pickling=use_pickling,
|
|
3303
3368
|
)
|
|
3304
3369
|
if output_command is None:
|
|
3305
3370
|
details = f"Attempted to serialize output value for parameter '{parameter.name}' on node '{node.name}'. The output value will not be restored in anything that attempts to deserialize or save this node. The value for this parameter was not serialized because it did not match Griptape Nodes' criteria for serializability. To remedy, either update the value's type to support serializability or mark the parameter as not serializable by setting serializable=False when creating the parameter."
|
|
@@ -3588,6 +3653,30 @@ class NodeManager:
|
|
|
3588
3653
|
result_details=f"Successfully set lock state to {node.lock} for node '{node_name}'.",
|
|
3589
3654
|
)
|
|
3590
3655
|
|
|
3656
|
+
def on_batch_set_lock_node_state_request(self, request: BatchSetNodeLockStateRequest) -> ResultPayload:
|
|
3657
|
+
updated: list[str] = []
|
|
3658
|
+
failed: dict[str, str] = {}
|
|
3659
|
+
for name in request.node_names:
|
|
3660
|
+
try:
|
|
3661
|
+
node = self.get_node_by_name(name)
|
|
3662
|
+
except ValueError as err:
|
|
3663
|
+
failed[name] = f"Node not found. Error: {err}"
|
|
3664
|
+
continue
|
|
3665
|
+
node.lock = request.lock
|
|
3666
|
+
updated.append(name)
|
|
3667
|
+
|
|
3668
|
+
if not updated:
|
|
3669
|
+
details = f"Failed to update any nodes. Failed: {failed}"
|
|
3670
|
+
return BatchSetNodeLockStateResultFailure(result_details=details)
|
|
3671
|
+
details = f"Successfully set lock state to {request.lock} for nodes: {', '.join(updated)}." + (
|
|
3672
|
+
f" Failed: {failed}" if failed else ""
|
|
3673
|
+
)
|
|
3674
|
+
return BatchSetNodeLockStateResultSuccess(
|
|
3675
|
+
updated_nodes=updated,
|
|
3676
|
+
failed_nodes=failed,
|
|
3677
|
+
result_details=details,
|
|
3678
|
+
)
|
|
3679
|
+
|
|
3591
3680
|
def on_send_node_message_request(self, request: SendNodeMessageRequest) -> ResultPayload:
|
|
3592
3681
|
"""Handle a SendNodeMessageRequest by calling the node's message callback.
|
|
3593
3682
|
|
|
@@ -44,6 +44,9 @@ from griptape_nodes.retained_mode.events.library_events import (
|
|
|
44
44
|
ListRegisteredLibrariesRequest,
|
|
45
45
|
)
|
|
46
46
|
from griptape_nodes.retained_mode.events.node_events import (
|
|
47
|
+
BatchSetNodeLockStateRequest,
|
|
48
|
+
BatchSetNodeLockStateResultFailure,
|
|
49
|
+
BatchSetNodeLockStateResultSuccess,
|
|
47
50
|
CreateNodeRequest,
|
|
48
51
|
CreateNodeResultFailure,
|
|
49
52
|
DeleteNodeRequest,
|
|
@@ -388,6 +391,20 @@ class RetainedMode:
|
|
|
388
391
|
result = GriptapeNodes().handle_request(request)
|
|
389
392
|
return result
|
|
390
393
|
|
|
394
|
+
@classmethod
|
|
395
|
+
def batch_set_lock_node_state(
|
|
396
|
+
cls, *, node_names: list[str], lock: bool = True
|
|
397
|
+
) -> BatchSetNodeLockStateResultSuccess | BatchSetNodeLockStateResultFailure:
|
|
398
|
+
"""Sets the lock state of multiple nodes.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
node_names (list[str]): Names of nodes to lock/unlock.
|
|
402
|
+
lock (bool): Whether to lock (True) or unlock (False) the nodes.
|
|
403
|
+
"""
|
|
404
|
+
request = BatchSetNodeLockStateRequest(node_names=node_names, lock=lock)
|
|
405
|
+
result = GriptapeNodes().handle_request(request)
|
|
406
|
+
return result
|
|
407
|
+
|
|
391
408
|
@classmethod
|
|
392
409
|
def get_connections_for_node(cls, node_name: str) -> ResultPayload:
|
|
393
410
|
"""Gets all connections associated with a node.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: griptape-nodes
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.70.0
|
|
4
4
|
Summary: Add your description here
|
|
5
|
-
Requires-Dist: griptape>=1.
|
|
5
|
+
Requires-Dist: griptape>=1.9.0
|
|
6
6
|
Requires-Dist: pydantic>=2.10.6
|
|
7
7
|
Requires-Dist: python-dotenv>=1.0.1
|
|
8
8
|
Requires-Dist: xdg-base-dirs>=6.0.2
|
|
9
9
|
Requires-Dist: httpx>=0.28.0,<1.0.0
|
|
10
|
-
Requires-Dist: websockets>=15.0.1,<
|
|
10
|
+
Requires-Dist: websockets>=15.0.1,<17.0.0
|
|
11
11
|
Requires-Dist: tomlkit>=0.13.2
|
|
12
12
|
Requires-Dist: uv>=0.6.16
|
|
13
13
|
Requires-Dist: fastapi>=0.115.12
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
griptape_nodes/__init__.py,sha256=WxWjICLxwuyZGDpPUyCmj047GbN7PIspi4YMWgmrrQc,671
|
|
2
2
|
griptape_nodes/__main__.py,sha256=fJhor6_1A27abwbnceyNheONP1iXkPzjjsV5jBEfF2M,144
|
|
3
3
|
griptape_nodes/api_client/__init__.py,sha256=9iyLcPbcXjxxLhhCSYQ5zgvlwxceyrNXDE8YhOIVH8g,216
|
|
4
|
-
griptape_nodes/api_client/client.py,sha256=
|
|
4
|
+
griptape_nodes/api_client/client.py,sha256=fNTs-xJL8deRWceGKBGOCeKwMt6Rd0vi-jCxniZk79E,9870
|
|
5
5
|
griptape_nodes/api_client/request_client.py,sha256=Z5lJVoG2a9hudTAQTnniaCHbBko0X1FyoakiQMimq7g,9713
|
|
6
6
|
griptape_nodes/app/.python-version,sha256=e1X45ntWI8S-8_ppEojalDfXnTq6FW3kjUgdsyrH0W0,5
|
|
7
7
|
griptape_nodes/app/__init__.py,sha256=DB-DTsgcNnbmEClXEouwzGhrmo3gHBCWXB9BkPGpdQI,90
|
|
8
|
-
griptape_nodes/app/app.py,sha256=
|
|
8
|
+
griptape_nodes/app/app.py,sha256=bbaRe1khQNRZ1fziDdeokkR-M3K7tvKDpCl4eVm-R4g,18014
|
|
9
9
|
griptape_nodes/app/watch.py,sha256=hKVP_SuV9C17bH1h9o4uIVTKH-IL_-0iyHaNYmILTWU,1594
|
|
10
10
|
griptape_nodes/bootstrap/__init__.py,sha256=ENv3SIzQ9TtlRrg1y4e4CnoBpJaFpFSkNpTFBV8X5Ls,25
|
|
11
11
|
griptape_nodes/bootstrap/utils/__init__.py,sha256=tlNEApJLZazcBNhxkTdup4URwznnz4nZxjSaRfFrTBM,31
|
|
@@ -69,24 +69,24 @@ griptape_nodes/exe_types/core_types.py,sha256=XrMT0Rf0bPZBcx06f1GUTi5G_IwLgdyzGj
|
|
|
69
69
|
griptape_nodes/exe_types/flow.py,sha256=2iAh3vN5wnMVxTc5jcPBg9TSiASq1DGIm5jgpO9Bdq4,5732
|
|
70
70
|
griptape_nodes/exe_types/node_groups/__init__.py,sha256=u91XCSR4OAAr6x5kYq8i14mtHEWGQF_fSDUsWHmiOdY,346
|
|
71
71
|
griptape_nodes/exe_types/node_groups/base_iterative_node_group.py,sha256=sPPy3Psl-Ku_R46upWm_8hIGFLNPeLpUBN_Sm4RzXzg,9655
|
|
72
|
-
griptape_nodes/exe_types/node_groups/base_node_group.py,sha256=
|
|
72
|
+
griptape_nodes/exe_types/node_groups/base_node_group.py,sha256=loDdJKllRPpWSSk-jJpqbBto80yn5oZGc6Jl-VXa_8A,3955
|
|
73
73
|
griptape_nodes/exe_types/node_groups/subflow_node_group.py,sha256=UlZS95TKUCWiHgg6z4Wm1t9xXfUjWhk0L8pB5cXMcV0,48361
|
|
74
|
-
griptape_nodes/exe_types/node_types.py,sha256=
|
|
74
|
+
griptape_nodes/exe_types/node_types.py,sha256=Hrzun9DN4FA-Yk-YQXBFyGrH1-kzszd9eVq4y6rmV5Y,84226
|
|
75
75
|
griptape_nodes/exe_types/param_components/README.md,sha256=mcNFxJIan9CGTnecsrJ8mkHC55dlA3fb7k4HFznou-k,14850
|
|
76
76
|
griptape_nodes/exe_types/param_components/__init__.py,sha256=ocm75WnsgiD6ozKVGFhoH9cQe_FEzeF2osxrRujOes0,60
|
|
77
77
|
griptape_nodes/exe_types/param_components/api_key_provider_parameter.py,sha256=MHn5zYb2vEf4bGBfbnTjCfVYEbpZtXThb8JJAAMpuR8,7766
|
|
78
78
|
griptape_nodes/exe_types/param_components/artifact_url/__init__.py,sha256=LKAGdP8VBSOTx8iq8kEvxZVDgMIS5TXSLntZqBEJ7yk,40
|
|
79
79
|
griptape_nodes/exe_types/param_components/artifact_url/public_artifact_url_parameter.py,sha256=2A4Jn7Xgi6KPM087wnVhoH3k5GnqxLFt3MV56SwYIYI,6610
|
|
80
|
-
griptape_nodes/exe_types/param_components/execution_status_component.py,sha256=
|
|
80
|
+
griptape_nodes/exe_types/param_components/execution_status_component.py,sha256=OBKTNW9q3-Ges6hxH--dyh1qbwU2O8WnwTNVRU_wW8s,6863
|
|
81
81
|
griptape_nodes/exe_types/param_components/huggingface/__init__.py,sha256=YeVFck-9C341Bt7TiWEvPdD63o9qkaNu2KjmzT9CQOI,39
|
|
82
82
|
griptape_nodes/exe_types/param_components/huggingface/huggingface_model_parameter.py,sha256=rEGN4kvblSAlRh7pD73U__wzAtVzDYWYlDC-k1nKtyM,6395
|
|
83
83
|
griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_file_parameter.py,sha256=c61de3mbkc5FvVkf5vubtD0XfThDInTfibAtYhZKcKA,4265
|
|
84
84
|
griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_parameter.py,sha256=zcBRQP0eZJloSdPQwJFw89B6QDHECnrosRZUy8mE2fM,1401
|
|
85
85
|
griptape_nodes/exe_types/param_components/huggingface/huggingface_repo_variant_parameter.py,sha256=FaaDZ4dvZJCnpqSOKfJ5nR1klgl07JZto2A7gxhUi3o,5290
|
|
86
86
|
griptape_nodes/exe_types/param_components/huggingface/huggingface_utils.py,sha256=cE0Ht81kDcZjlN_2VoRirCA4zMlrG9GFlcptn-gC2tU,4696
|
|
87
|
-
griptape_nodes/exe_types/param_components/log_parameter.py,sha256=
|
|
87
|
+
griptape_nodes/exe_types/param_components/log_parameter.py,sha256=_v6NH1lz9FrEKf2uMIOlwxzKTy5Vl3EAZai54lAMF1g,4313
|
|
88
88
|
griptape_nodes/exe_types/param_components/progress_bar_component.py,sha256=GrAFTOrLNAx6q9zfOqiioPTG_NLHKhTe9NiZOo6zGSc,1949
|
|
89
|
-
griptape_nodes/exe_types/param_components/seed_parameter.py,sha256=
|
|
89
|
+
griptape_nodes/exe_types/param_components/seed_parameter.py,sha256=I48cVAojrD5oX4CT7v0x9LX6MrKVklywkp8IjE5pGIo,2321
|
|
90
90
|
griptape_nodes/exe_types/param_types/__init__.py,sha256=xEEmKvIFF6M7zVjQZCupbbv6SZKt-itD-rPtfRhxJVg,53
|
|
91
91
|
griptape_nodes/exe_types/param_types/parameter_audio.py,sha256=9oIBtDg6miZDD_5y8VWr6XXjYhsRb9HjSKoaLdgqaHA,9534
|
|
92
92
|
griptape_nodes/exe_types/param_types/parameter_bool.py,sha256=VS76CODOy7_1MJI9spxmi9VwL3fwCxRKaj_8zpqB7dw,8215
|
|
@@ -130,7 +130,7 @@ griptape_nodes/retained_mode/events/library_events.py,sha256=4NUc3uoLgofo1X9nrCV
|
|
|
130
130
|
griptape_nodes/retained_mode/events/logger_events.py,sha256=jYlxzPomgCsJuPtJ0znWBhD8QJfC8qC4xfChDiuVuyg,705
|
|
131
131
|
griptape_nodes/retained_mode/events/mcp_events.py,sha256=fs83jAQamhwNC9Zt8UNkBKd6iTids8531V_RMnGj__o,11008
|
|
132
132
|
griptape_nodes/retained_mode/events/model_events.py,sha256=jXm-v-_Uxysn4MJ7a80_uIphrxTHgua3BGgHGyy3T_Y,9232
|
|
133
|
-
griptape_nodes/retained_mode/events/node_events.py,sha256=
|
|
133
|
+
griptape_nodes/retained_mode/events/node_events.py,sha256=9yTdTrFNd5JATvHk5x3ucznMou3ZzYxgpCgNjAF-GuU,38760
|
|
134
134
|
griptape_nodes/retained_mode/events/object_events.py,sha256=cJaqEU73Lzf1RRxJrFqEpl8eTr-gDhKpXKywJ-vVCJQ,2631
|
|
135
135
|
griptape_nodes/retained_mode/events/os_events.py,sha256=fVraPXCz48kDpCTttJFtsyfTfkaLSfTX57hexYSD7I8,23429
|
|
136
136
|
griptape_nodes/retained_mode/events/parameter_events.py,sha256=TazVXxvfv64n3XJzToOQKiWQ1UIzrUAB4ri_QIvZ2ng,26968
|
|
@@ -148,7 +148,7 @@ griptape_nodes/retained_mode/managers/__init__.py,sha256=OTXysKusqYCQeAYwnVj4PbE
|
|
|
148
148
|
griptape_nodes/retained_mode/managers/agent_manager.py,sha256=FOKrcHEBw6M-RmfWTWEQmV-9iy9cD1zHiiDUDMqJHE4,28307
|
|
149
149
|
griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py,sha256=LyWzHQKmyDh-2zh2PIahdYyAthf_rMYs4zvhtVo-LsU,3423
|
|
150
150
|
griptape_nodes/retained_mode/managers/config_manager.py,sha256=74AMeaCS0eOeFbzMk5I54MtB7-SNQbwlx_-O6zBBQRo,26739
|
|
151
|
-
griptape_nodes/retained_mode/managers/context_manager.py,sha256=
|
|
151
|
+
griptape_nodes/retained_mode/managers/context_manager.py,sha256=n-r6-Zzyq3-9QBAyIZO7w7YC7PGBuIouFLH44ef06E8,21956
|
|
152
152
|
griptape_nodes/retained_mode/managers/engine_identity_manager.py,sha256=-31364A03kU0YmAx3nM7nHdWfKnkej5Cawt_Plbwa68,10526
|
|
153
153
|
griptape_nodes/retained_mode/managers/event_manager.py,sha256=jiUX3WW6Hz0Z4Y1dK1X7fMwZawT3_BOKl_Dbiui-iNQ,26933
|
|
154
154
|
griptape_nodes/retained_mode/managers/fitness_problems/__init__.py,sha256=H_Wwfn1k_IaxwRxgbw3-seb1HWbcxl2Cvhw7wB7bCo8,75
|
|
@@ -201,12 +201,12 @@ griptape_nodes/retained_mode/managers/fitness_problems/workflows/node_type_not_f
|
|
|
201
201
|
griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_not_found_problem.py,sha256=kPhaIeDxp0duxJBJLKFiYp269kEDsCx3uVLnkKbF2gk,895
|
|
202
202
|
griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_problem.py,sha256=NLAoF_x7g5tL70qZtPVFI8xeM1jPZNsm7FKt9nkuGBc,542
|
|
203
203
|
griptape_nodes/retained_mode/managers/fitness_problems/workflows/workflow_schema_version_problem.py,sha256=rUnbBBnGwgq5WTVPt2G4pGP3gVPoX5xvCdTkRPBmP04,1328
|
|
204
|
-
griptape_nodes/retained_mode/managers/flow_manager.py,sha256=
|
|
204
|
+
griptape_nodes/retained_mode/managers/flow_manager.py,sha256=BKWLpc-udlZ4n1rlKINHFS-Jj6wBqoCSdD7x0FyNr5o,220266
|
|
205
205
|
griptape_nodes/retained_mode/managers/library_manager.py,sha256=paogGavZj2MDOYvfUklhjORQg16YdpVGBxBncVSxtR0,192265
|
|
206
206
|
griptape_nodes/retained_mode/managers/mcp_manager.py,sha256=AEHG1SqFc3g5hOImOHaH7ZjOkmgNAavmQgG9osXVGkE,16018
|
|
207
207
|
griptape_nodes/retained_mode/managers/model_manager.py,sha256=3lj2X8vIvDSERPtR2VEXNFEWy_D8H6muxRvD-PEx8U8,44845
|
|
208
|
-
griptape_nodes/retained_mode/managers/node_manager.py,sha256=
|
|
209
|
-
griptape_nodes/retained_mode/managers/object_manager.py,sha256=
|
|
208
|
+
griptape_nodes/retained_mode/managers/node_manager.py,sha256=BG0-z2-pDjzgS5VC3u3p7-jGUJ5nGSGSShbSv9WseoA,229244
|
|
209
|
+
griptape_nodes/retained_mode/managers/object_manager.py,sha256=ZpovmhnBKG_JCn4Pde9idlx2eBZjKvR7k9DHUYqD-r4,12882
|
|
210
210
|
griptape_nodes/retained_mode/managers/operation_manager.py,sha256=4Vn_79vHrawy3wJVUx52tfblO4mURww58nb5RtCTpKU,20190
|
|
211
211
|
griptape_nodes/retained_mode/managers/os_manager.py,sha256=Ttgj6R063p2Yf1lcdeSTB2xOTg94MIDCMPxO8FDczEQ,142397
|
|
212
212
|
griptape_nodes/retained_mode/managers/project_manager.py,sha256=-K-anrxEVKInFMPLY-cV3ipqEh8hMELGHKbecJJJVa8,49035
|
|
@@ -229,7 +229,7 @@ griptape_nodes/retained_mode/managers/user_manager.py,sha256=JAOOKDhUfIbj0CJ5EHR
|
|
|
229
229
|
griptape_nodes/retained_mode/managers/variable_manager.py,sha256=TnuqHSRK9Yiu_EtKxQksF9SyyQb72lbFQuTQZdpBxeE,24116
|
|
230
230
|
griptape_nodes/retained_mode/managers/version_compatibility_manager.py,sha256=kaCtmNMqJW-mvLCFHf77wbBZbc3CgW2h8fYYkLkNrPs,17041
|
|
231
231
|
griptape_nodes/retained_mode/managers/workflow_manager.py,sha256=n6jmr966Y_0MPd9aaOssX2CYgojf_mNRxC07990Anec,217769
|
|
232
|
-
griptape_nodes/retained_mode/retained_mode.py,sha256=
|
|
232
|
+
griptape_nodes/retained_mode/retained_mode.py,sha256=fJNAVyheqjXFOh8--VAmJBLWlNgMyRWNghG_0u8B-1w,72415
|
|
233
233
|
griptape_nodes/retained_mode/utils/__init__.py,sha256=W5dvv8YwvVVq_8eVTgMd3Z_VB_Dtq1sIIVq8745QH_I,52
|
|
234
234
|
griptape_nodes/retained_mode/utils/name_generator.py,sha256=IZLahtfP3XC79XApLdGoZ0IKKUkgiITpd16RK7NbyEs,2524
|
|
235
235
|
griptape_nodes/retained_mode/variable_types.py,sha256=GVrSWMB3gEDAufSPOBXbNfIRhA9M43MoxpqLyuIg_HE,435
|
|
@@ -276,7 +276,7 @@ griptape_nodes/version_compatibility/versions/v0_65_5/__init__.py,sha256=4UyspOV
|
|
|
276
276
|
griptape_nodes/version_compatibility/versions/v0_65_5/flux_2_removed_parameters.py,sha256=jOlmY5kKHXh8HPzAUtvwMJqzD4bP7pkE--yHUb7jTRA,3305
|
|
277
277
|
griptape_nodes/version_compatibility/versions/v0_7_0/__init__.py,sha256=IzPPmGK86h2swfGGTOHyVcBIlOng6SjgWQzlbf3ngmo,51
|
|
278
278
|
griptape_nodes/version_compatibility/versions/v0_7_0/local_executor_argument_addition.py,sha256=Thx8acnbw5OychhwEEj9aFxvbPe7Wgn4V9ZmZ7KRZqc,2082
|
|
279
|
-
griptape_nodes-0.
|
|
280
|
-
griptape_nodes-0.
|
|
281
|
-
griptape_nodes-0.
|
|
282
|
-
griptape_nodes-0.
|
|
279
|
+
griptape_nodes-0.70.0.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
|
|
280
|
+
griptape_nodes-0.70.0.dist-info/entry_points.txt,sha256=qvevqd3BVbAV5TcantnAm0ouqaqYKhsRO3pkFymWLWM,82
|
|
281
|
+
griptape_nodes-0.70.0.dist-info/METADATA,sha256=BF90w9kk-lZK3hgKOpZNlTFt_GubK2VhZ3g01FioCBQ,5373
|
|
282
|
+
griptape_nodes-0.70.0.dist-info/RECORD,,
|
|
File without changes
|