Skip to content

Commit 5027a3f

Browse files
committed
fix(eval): route eval-run/eval-set-run API calls by AgentId
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
1 parent fedbfa2 commit 5027a3f

2 files changed

Lines changed: 90 additions & 10 deletions

File tree

packages/uipath/src/uipath/_cli/_evals/_progress_reporter.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ def __init__(self):
102102
self._console = console_logger
103103
self._rich_console = Console()
104104
self._project_id = os.getenv("UIPATH_PROJECT_ID", None)
105-
if not self._project_id:
105+
self._agent_id = os.getenv("UIPATH_AGENT_ID") or self._project_id
106+
if not self._agent_id:
106107
logger.warning(
107108
"Cannot report data to StudioWeb. Please set UIPATH_PROJECT_ID."
108109
)
@@ -1133,7 +1134,7 @@ def _update_eval_run_spec(
11331134
return RequestSpec(
11341135
method="PUT",
11351136
endpoint=Endpoint(
1136-
f"{self._get_endpoint_prefix()}execution/agents/{self._project_id}/{endpoint_suffix}evalRun"
1137+
f"{self._get_endpoint_prefix()}execution/agents/{self._agent_id}/{endpoint_suffix}evalRun"
11371138
),
11381139
json=payload,
11391140
headers=self._tenant_header(),
@@ -1181,7 +1182,7 @@ def _update_coded_eval_run_spec(
11811182
return RequestSpec(
11821183
method="PUT",
11831184
endpoint=Endpoint(
1184-
f"{self._get_endpoint_prefix()}execution/agents/{self._project_id}/{endpoint_suffix}evalRun"
1185+
f"{self._get_endpoint_prefix()}execution/agents/{self._agent_id}/{endpoint_suffix}evalRun"
11851186
),
11861187
json=payload,
11871188
headers=self._tenant_header(),
@@ -1253,7 +1254,7 @@ def _create_eval_run_spec(
12531254
return RequestSpec(
12541255
method="POST",
12551256
endpoint=Endpoint(
1256-
f"{self._get_endpoint_prefix()}execution/agents/{self._project_id}/{endpoint_suffix}evalRun"
1257+
f"{self._get_endpoint_prefix()}execution/agents/{self._agent_id}/{endpoint_suffix}evalRun"
12571258
),
12581259
json=payload,
12591260
headers=self._tenant_header(),
@@ -1283,7 +1284,7 @@ def _create_eval_set_run_spec(
12831284
eval_set_id_value = str(uuid.uuid5(uuid.NAMESPACE_DNS, eval_set_id))
12841285

12851286
inner_payload: dict[str, Any] = {
1286-
"agentId": self._project_id,
1287+
"agentId": self._agent_id,
12871288
"evalSetId": eval_set_id_value,
12881289
"agentSnapshot": agent_snapshot.model_dump(by_alias=True),
12891290
# Backend expects integer status
@@ -1309,7 +1310,7 @@ def _create_eval_set_run_spec(
13091310
return RequestSpec(
13101311
method="POST",
13111312
endpoint=Endpoint(
1312-
f"{self._get_endpoint_prefix()}execution/agents/{self._project_id}/{endpoint_suffix}evalSetRun"
1313+
f"{self._get_endpoint_prefix()}execution/agents/{self._agent_id}/{endpoint_suffix}evalSetRun"
13131314
),
13141315
json=payload,
13151316
headers=self._tenant_header(),
@@ -1374,7 +1375,7 @@ def _update_eval_set_run_spec(
13741375
return RequestSpec(
13751376
method="PUT",
13761377
endpoint=Endpoint(
1377-
f"{self._get_endpoint_prefix()}execution/agents/{self._project_id}/{endpoint_suffix}evalSetRun"
1378+
f"{self._get_endpoint_prefix()}execution/agents/{self._agent_id}/{endpoint_suffix}evalSetRun"
13781379
),
13791380
json=payload,
13801381
headers=self._tenant_header(),
@@ -1406,12 +1407,12 @@ def _get_eval_runs_spec(
14061407

14071408
if is_coded:
14081409
endpoint_path = (
1409-
f"{prefix}execution/agents/{self._project_id}/coded/"
1410+
f"{prefix}execution/agents/{self._agent_id}/coded/"
14101411
f"evalSets/{eval_set_id}/evalSetRuns/{eval_set_run_id}/evalRuns"
14111412
)
14121413
else:
14131414
endpoint_path = (
1414-
f"{prefix}execution/agents/{self._project_id}/"
1415+
f"{prefix}execution/agents/{self._agent_id}/"
14151416
f"evalSets/{eval_set_id}/evalSetRuns/{eval_set_run_id}/evalRuns"
14161417
)
14171418

packages/uipath/tests/cli/eval/test_progress_reporter.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,4 +927,83 @@ def test_build_evaluator_snapshot_skips_non_string_model(self, progress_reporter
927927
snapshot = progress_reporter._build_evaluator_snapshot(evaluator)
928928

929929
assert snapshot["prompt"] == "Evaluate this"
930-
assert "model" not in snapshot
930+
931+
932+
class TestAgentIdRouting:
933+
"""Eval-set/eval-run API URLs route by AgentId, not file-source project.
934+
935+
For local-workspace eval runs the file-source project (UIPATH_PROJECT_ID,
936+
typically the cloud debug project's GUID) differs from the logical agent
937+
(UIPATH_AGENT_ID). The route URL must reflect the logical agent so backend
938+
auth/ownership/telemetry don't see the per-run debug project as the agent.
939+
File fetching (UiPathConfig.project_id) is unaffected.
940+
"""
941+
942+
def _make_reporter(self, monkeypatch, project_id, agent_id):
943+
monkeypatch.setenv("UIPATH_URL", "https://test.uipath.com")
944+
monkeypatch.setenv("UIPATH_ACCESS_TOKEN", "test-token")
945+
monkeypatch.setenv("UIPATH_TENANT_ID", "test-tenant-id")
946+
if project_id is not None:
947+
monkeypatch.setenv("UIPATH_PROJECT_ID", project_id)
948+
else:
949+
monkeypatch.delenv("UIPATH_PROJECT_ID", raising=False)
950+
if agent_id is not None:
951+
monkeypatch.setenv("UIPATH_AGENT_ID", agent_id)
952+
else:
953+
monkeypatch.delenv("UIPATH_AGENT_ID", raising=False)
954+
return StudioWebProgressReporter()
955+
956+
def test_agent_id_used_in_url_when_both_set(self, monkeypatch):
957+
reporter = self._make_reporter(
958+
monkeypatch, project_id="debug-project-guid", agent_id="real-agent-id"
959+
)
960+
assert reporter._agent_id == "real-agent-id"
961+
assert reporter._project_id == "debug-project-guid"
962+
963+
from uipath._cli._evals._progress_reporter import StudioWebAgentSnapshot
964+
965+
spec = reporter._create_eval_set_run_spec(
966+
eval_set_id="test-eval-set",
967+
agent_snapshot=StudioWebAgentSnapshot(
968+
input_schema={"type": "object"}, output_schema={"type": "object"}
969+
),
970+
no_of_evals=1,
971+
is_coded=False,
972+
)
973+
assert "/agents/real-agent-id/" in spec.endpoint
974+
assert "/agents/debug-project-guid/" not in spec.endpoint
975+
976+
def test_agent_id_in_eval_set_run_payload(self, monkeypatch):
977+
reporter = self._make_reporter(
978+
monkeypatch, project_id="debug-project-guid", agent_id="real-agent-id"
979+
)
980+
981+
from uipath._cli._evals._progress_reporter import StudioWebAgentSnapshot
982+
983+
spec = reporter._create_eval_set_run_spec(
984+
eval_set_id="test-eval-set",
985+
agent_snapshot=StudioWebAgentSnapshot(
986+
input_schema={"type": "object"}, output_schema={"type": "object"}
987+
),
988+
no_of_evals=1,
989+
is_coded=False,
990+
)
991+
assert spec.json["agentId"] == "real-agent-id"
992+
993+
def test_falls_back_to_project_id_when_agent_id_unset(self, monkeypatch):
994+
reporter = self._make_reporter(
995+
monkeypatch, project_id="cloud-project-id", agent_id=None
996+
)
997+
assert reporter._agent_id == "cloud-project-id"
998+
999+
from uipath._cli._evals._progress_reporter import StudioWebAgentSnapshot
1000+
1001+
spec = reporter._create_eval_set_run_spec(
1002+
eval_set_id="test-eval-set",
1003+
agent_snapshot=StudioWebAgentSnapshot(
1004+
input_schema={"type": "object"}, output_schema={"type": "object"}
1005+
),
1006+
no_of_evals=1,
1007+
is_coded=False,
1008+
)
1009+
assert "/agents/cloud-project-id/" in spec.endpoint

0 commit comments

Comments
 (0)