Scope and IdRef - cprima-forks/uipath-ai-skills GitHub Wiki
Scope and IdRef
Two independent identity systems run through every generated workflow: IdRef for Studio's designer state, and ScopeGuid/ScopeIdentifier for Modern UI Automation activity scoping.
IdRef: _IdRefCounter
Every activity that Studio's designer tracks needs a sap2010:WorkflowViewState.IdRef attribute with a unique value. The _IdRefCounter generates these:
class _IdRefCounter:
def next(self, prefix: str) -> str:
self._counts[prefix] = self._counts.get(prefix, 0) + 1
return f"{prefix}_{self._counts[prefix]}"
A single counter instance is created per generate_workflow call and passed down through all recursive _generate_activity calls. Counters are per-prefix, so the sequence is:
NTypeInto_1, NClick_1, NTypeInto_2, NClick_2, Sequence_1, ...
The prefix comes from _GenEntry.idref. For generators not in the registry, _derive_idref_prefix converts the gen name to PascalCase with acronym corrections (Csv → CSV, Pdf → PDF, Json → JSON).
Container generators often consume multiple IdRef values in one call — for example, gen_retryscope needs an IdRef for the RetryScope itself and another for its inner Sequence.
ScopeGuid vs ScopeIdentifier
Modern UI Automation activities (uix: namespace) use a UUID to link child activities to their containing NApplicationCard. This UUID appears under two different attribute names:
| Element | Attribute name | Value |
|---|---|---|
uix:NApplicationCard |
ScopeGuid |
UUID generated at scaffold time |
Every child uix: activity |
ScopeIdentifier |
Same UUID |
The same UUID value, two attribute names. ScopeGuid is the declaration; ScopeIdentifier is the reference.
When _make_simple_container_handler is called with new_scope=True (for all NApplicationCard variants), it generates a new UUID for the card and passes it as scope_id to every child _generate_activity call. Those child generators write it as their ScopeIdentifier.
Root Scope
Workflows that contain no NApplicationCard still need a scope_id for child activities. generate_workflow generates a single root UUID at the start:
root_scope = str(uuid.uuid4())
This root UUID is passed to every top-level _generate_activity call as scope_id. For non-UI activities it is unused; for any UI activity at the top level of a workflow (outside a card), it provides the scope reference.