Conversation
Local-workspace eval runs distinguish two project IDs that the SDK had been collapsing into one: the *file-source project* (cloud project the worker fetches package files from) and the *logical agent* (the agent the user authored). For cloud projects the two are equal; for local workspaces they differ — file source is the per-run debug project's GUID, agent is the user's local agent UUID. When the worker runs under a service-account context (serverless), its JWT carries the service account's `sub` claim, not the real triggering user. Telemetry tagged from the JWT therefore attributes runs to the wrong identity. This change introduces three env vars the backend can set so the SDK tags telemetry with the right identities: - UIPATH_FILE_SOURCE_PROJECT_ID — preferred over UIPATH_PROJECT_ID for file-source semantics; falls back to UIPATH_PROJECT_ID so existing cloud deployments are unaffected. - UIPATH_AGENT_ID — the logical agent. Telemetry "AgentId" is now tagged with this when set, falling back to the file-source project for cloud runs. - UIPATH_CLOUD_USER_ID — the real user. Eval and CLI telemetry prefer this over the JWT sub claim, falling back to the JWT for older backends. The route URL the SDK uses for eval-run callbacks is unchanged (stays on file-source project) — backend-side ownership inheritance in CreateEvalRunAsync handles the AgentId/CloudUserId attribution end-to-end. This SDK change is the telemetry/observability half. 10 new tests in packages/uipath-platform/tests/common/ cover the fallback chain for each property. Existing CLI telemetry tests unchanged and still pass. Refs: AE-1396, PC-4407
1. Pin uipath-platform>=0.1.43 in uipath/pyproject.toml. The new UiPathConfig.agent_id / cloud_user_id properties only exist after the 0.1.43 bump; the old >=0.1.42 constraint allowed a skewed install where uipath==2.10.61 calls AttributeError-raising properties. 2. Restrict the CLI telemetry AgentId override to the explicit UIPATH_AGENT_ID env var instead of UiPathConfig.agent_id (which falls back to project_id). Prevents silent regression of non-eval CLI contexts that set UIPATH_PROJECT_ID — those continue to tag AgentId from PROJECT_KEY as before. Refs: AE-1396
AAgnihotry
reviewed
May 1, 2026
Contributor
AAgnihotry
left a comment
There was a problem hiding this comment.
where are we passing these values to the eval runs and evalset runs
The SDK's StudioWebProgressReporter was using UIPATH_PROJECT_ID for
both the API URL (/api/execution/agents/{id}/evalRun) and the file
fetch context. For local-workspace runs those are different IDs:
file source is the cloud debug project's GUID, agent is the user's
logical agent.
Honoring the AgentId in API calls so the route URL reflects the real
logical agent. File fetching (UiPathConfig.project_id, used by
StudioClient/ResourceOverwritesContext in cli_eval.py) keeps using
the file-source project, since that is where the worker's package
files live.
Changes:
- StudioWebProgressReporter now exposes self._agent_id (UIPATH_AGENT_ID
with fallback to self._project_id). Every API URL construction and
the agentId payload field now use _agent_id.
- self._project_id is preserved for the file-source semantic (env-var
fallback for AgentId resolution); no remaining read sites in the
reporter, but kept as the explicit "if file source ever needs
callbacks" hook.
Tests added in TestAgentIdRouting (test_progress_reporter.py):
- _agent_id used in URL when both UIPATH_AGENT_ID and UIPATH_PROJECT_ID set
- agentId payload field carries _agent_id, not file source
- Falls back to project_id (file source) when UIPATH_AGENT_ID unset
1826 reporter tests pass (3 new).
Refs: AE-1396
… UI filter projectFilesSource is the Local/Cloud discriminator the UI filters by (`?projectFilesSource=1` for local-workspace runs), not a project ID. Until now the SDK didn't send it on the eval-run / eval-set-run callbacks, so the backend created every worker-spawned row defaulting to Cloud and the UI's local-runs filter never matched them. Reads UIPATH_PROJECT_FILES_SOURCE (string Local/Cloud) once at reporter construction and maps it to the backend's enum integer (Local=1, Cloud=0). Adds it to: POST eval set run payload POST eval run payload PUT eval run (legacy) payload PUT eval run (coded) payload PUT eval set run payload GET eval runs (resume lookup) query parameter When the env var is unset (cloud-project case or older backend that doesn't emit it) the field is omitted from payloads/params, preserving existing behaviour. 14 new tests in TestProjectFilesSourcePropagation covering the parametrized env-var resolution (Local/Cloud/numeric/garbage), each of the six request shapes carries the right value, and absence-omits-field. 1840 reporter tests pass. Refs: AE-1396
UIPATH_PROJECT_ID already carries the file-source semantic (cloud project the worker fetches files from). UIPATH_FILE_SOURCE_PROJECT_ID was an alias that added a third name for the same value without adding meaning. UiPathConfig.project_id now reads UIPATH_PROJECT_ID directly — no fallback chain. UiPathConfig.agent_id still falls back to project_id when UIPATH_AGENT_ID is unset (cloud-project case where the two are equal). Updated config tests; existing reporter/CLI telemetry behaviour unchanged. Refs: AE-1396
mjnovice
approved these changes
May 1, 2026
🚨 Heads up:
|
AAgnihotry
approved these changes
May 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The SDK now distinguishes the logical agent the user authored from the file-source project the worker fetches files from. Previously these were collapsed onto
UIPATH_PROJECT_ID, which works for cloud projects but is wrong for local-workspace eval runs (whereprepareForCustomDebugcreates a separate cloud debug project).Three behaviors change:
/api/execution/agents/{id}/evalRunand theagentIdpayload field now use the logical agent ID.AgentIdwith the logical agent, not the file-source project — dashboards group by what the user authored.CloudUserIdprefers the explicit env var over the JWTsubclaim, so service-account-spawned workers tag the real triggering user.File fetching (
UiPathConfig.project_id, used byStudioClient/ResourceOverwritesContextincli_eval.pyandcli_debug.py) stays on the file-source project — that's where the worker's package files actually live.Env var contract
UIPATH_PROJECT_IDUiPathConfig.project_id;StudioClient/ResourceOverwritesContextuse it for file fetching.UIPATH_AGENT_IDUiPathConfig.agent_id(falls back toproject_id). Used for eval API URL routing inStudioWebProgressReporterand telemetryAgentIdtagging.UIPATH_CLOUD_USER_IDsubclaim.UIPATH_PROJECT_FILES_SOURCELocalorClouddiscriminator the UI filters by.?projectFilesSource=1filter.How env vars flow
sequenceDiagram autonumber actor U as User participant FE as Studio Web (FE) participant API as Agents Backend participant ORC as Orchestrator participant HDN as hdens worker (Python runtime) participant SDK as uipath-python SDK U->>FE: Start eval run FE->>API: POST /startMultipleEvaluators<br/>?debugProjectId={debugId} Note over API: Builds env vars:<br/>UIPATH_PROJECT_ID = debugProjectId ?? agentId<br/>UIPATH_AGENT_ID = real agentId<br/>UIPATH_CLOUD_USER_ID = session.UserId<br/>UIPATH_PROJECT_FILES_SOURCE = Local/Cloud API->>ORC: ServerlessStartJobDto envVars newline-joined ORC->>HDN: Dispatch job Note over HDN: PythonCodedJobExecutor<br/>EnsureEnvironmentVariablesParsed()<br/>(no allowlist - every UIPATH_* flows through) HDN->>HDN: os.environ.update(env_vars)<br/>(via cli_server.py for pooled mode) HDN->>SDK: Invoke uipath eval rect rgb(240, 248, 255) Note over SDK: API callbacks use UIPATH_AGENT_ID SDK->>API: POST /api/execution/agents/{UIPATH_AGENT_ID}/evalSetRun<br/>{ projectFilesSource: 1, ... } SDK->>API: POST /api/execution/agents/{UIPATH_AGENT_ID}/evalRun<br/>{ projectFilesSource: 1, ... } SDK->>API: GET /api/execution/agents/.../evalRuns<br/>?projectFilesSource=1 end rect rgb(245, 245, 245) Note over SDK: File fetching uses UIPATH_PROJECT_ID (file source) SDK->>API: StudioClient(UIPATH_PROJECT_ID)<br/>(ResourceOverwritesContext) end rect rgb(248, 240, 255) Note over SDK: Telemetry tagged with both SDK->>SDK: properties[AgentId] = UIPATH_AGENT_ID<br/>properties[ProjectId] = UIPATH_PROJECT_ID<br/>properties[CloudUserId] = UIPATH_CLOUD_USER_ID endFor cloud runs,
UIPATH_AGENT_IDandUIPATH_PROJECT_IDare equal — the diagram collapses to today's behaviour. For local-workspace runs they differ and the SDK keeps them straight.Why this matters
/agents/{debug-project}/evalRuneven though the row should be attributed to the logical agent. Authz, telemetry dimensions, cache keys, and any future code consuming the route param would all see the debug project as if it were the agent.cli_server.pycross-contamination is mitigated by the existingos.environ.clear() + update(baseline) + update(env_vars)pattern — every job request gets a fresh env. The new variables follow the same pipeline.UIPATH_AGENT_ID) falls back toUIPATH_PROJECT_IDand behaves identically to today.Files touched
Tests
test_config_env_vars.py— fallback chain for each propertyTestAgentIdRoutingintest_progress_reporter.py— URL routing, payload field, fallback to project_idShip sequence
Jira
🤖 Generated with Claude Code