1+ from __future__ import annotations
12from typing import Any , Dict
23from aiida_workgraph .task import ChildTaskSet , Task
34from aiida_workgraph import task , namespace , meta
89from node_graph .node_spec import NodeSpec
910from node_graph .socket_spec import SocketSpec , SocketSpecMeta
1011from typing import Annotated
11- from aiida_workgraph .executors .builtins import get_item , update_ctx , get_context , select
12+ from aiida_workgraph .executors .builtins import update_ctx , get_context , select , return_input
13+ from node_graph .node import BuiltinPolicy
1214
1315
1416class GraphLevelTask (_GraphIOSharedMixin , Task ):
@@ -41,7 +43,7 @@ def __init__(self, *args, **kwargs):
4143 super ().__init__ (* args , ** kwargs )
4244 self .children = ChildTaskSet (parent = self )
4345
44- def add_task (self , * args , ** kwargs ):
46+ def add_task (self , * args , ** kwargs ) -> Task :
4547 """Syntactic sugar to add a task to the zone."""
4648 task = self .graph .add_task (* args , ** kwargs )
4749 self .children .add (task )
@@ -92,8 +94,9 @@ class Map(Zone):
9294 node_type = 'MAP' ,
9395 catalog = 'Control' ,
9496 inputs = namespace (
95- source = Annotated [ Any , SocketSpec ('workgraph.any' , link_limit = 100000 )] ,
97+ source = SocketSpec ('workgraph.any' , link_limit = 100000 ),
9698 ),
99+ outputs = namespace (),
97100 base_class_path = 'aiida_workgraph.tasks.builtins.Map' ,
98101 )
99102
@@ -109,14 +112,29 @@ def item(self):
109112 map_item_task = self .add_task ('workgraph.map_item' )
110113 return map_item_task .outputs
111114
112- def gather (self , socket : BaseSocket ) -> None :
113- gather_item = self .graph .add_task ('workgraph.gather_item' )
114- self .graph .add_link (socket , gather_item .inputs .value )
115- return gather_item .outputs .values
115+ @property
116+ def gather_item_task (self ) -> Task | None :
117+ for child in self .children :
118+ if child .identifier == 'workgraph.gather_item' :
119+ return child
120+ gather_item = self .add_task ('workgraph.gather_item' )
121+ return gather_item
122+
123+ def gather (self , sockets : Dict [str , BaseSocket ]) -> None :
124+ gather_item = self .gather_item_task
125+ for name in sockets :
126+ gather_item .add_input_spec ('workgraph.any' , name = name )
127+ self .add_output_spec ('workgraph.any' , name = name )
128+ gather_item .set_inputs (sockets )
129+ return gather_item .outputs
130+
116131
117132class MapItem (Task ):
118133 """MapItem"""
119134
135+ # turn off framework builtins for these graph-level nodes
136+ _BUILTINS_POLICY = BuiltinPolicy (input_wait = False , output_wait = False , default_output = False )
137+
120138 _default_spec = NodeSpec (
121139 identifier = 'workgraph.map_item' ,
122140 node_type = 'Normal' ,
@@ -125,32 +143,26 @@ class MapItem(Task):
125143 source = SocketSpec ('workgraph.any' , link_limit = 100000 , meta = SocketSpecMeta (required = False )),
126144 key = SocketSpec ('workgraph.string' , meta = SocketSpecMeta (required = False )),
127145 ),
128- outputs = namespace (item = SocketSpec ('workgraph.any' )),
129- executor = RuntimeExecutor .from_callable (get_item ),
146+ outputs = namespace (key = str , value = any ),
130147 base_class_path = 'aiida_workgraph.tasks.builtins.MapItem' ,
131148 )
132149
133150
134151class GatherItem (Task ):
135152 """GatherItem"""
136153
137- identifier = 'workgraph.gather_item'
138- name = 'GatherItem'
139- node_type = 'Normal'
140- catalog = 'Control'
141-
142- def create_sockets (self ) -> None :
143- self .inputs ._clear ()
144- self .outputs ._clear ()
154+ # turn off framework builtins for these graph-level nodes
155+ _BUILTINS_POLICY = BuiltinPolicy (input_wait = True , output_wait = False , default_output = False )
145156
146- self .add_input ('workgraph.any' , 'value' )
147- self .add_output ('workgraph.namespace' , 'values' )
148- self .add_output ('workgraph.any' , '_wait' )
149-
150- def get_executor (self ):
151- from aiida_workgraph .executors .builtins import return_inputs
152-
153- return RuntimeExecutor .from_callable (return_inputs )
157+ _default_spec = NodeSpec (
158+ identifier = 'workgraph.gather_item' ,
159+ node_type = 'Normal' ,
160+ catalog = 'Control' ,
161+ inputs = namespace (),
162+ outputs = namespace (),
163+ executor = RuntimeExecutor .from_callable (return_input ),
164+ base_class_path = 'aiida_workgraph.tasks.builtins.GatherItem' ,
165+ )
154166
155167
156168class SetContext (Task ):
0 commit comments