uipath 2.1.21__tar.gz → 2.1.22__tar.gz

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.
Files changed (239) hide show
  1. {uipath-2.1.21 → uipath-2.1.22}/PKG-INFO +1 -1
  2. {uipath-2.1.21 → uipath-2.1.22}/pyproject.toml +1 -1
  3. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_push/sw_file_handler.py +97 -56
  4. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_studio_project.py +79 -32
  5. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_push.py +100 -69
  6. {uipath-2.1.21 → uipath-2.1.22}/uv.lock +1 -1
  7. {uipath-2.1.21 → uipath-2.1.22}/.cursorrules +0 -0
  8. {uipath-2.1.21 → uipath-2.1.22}/.editorconfig +0 -0
  9. {uipath-2.1.21 → uipath-2.1.22}/.gitattributes +0 -0
  10. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/cd.yml +0 -0
  11. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/ci.yml +0 -0
  12. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/commitlint.yml +0 -0
  13. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/lint.yml +0 -0
  14. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/publish-dev.yml +0 -0
  15. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/publish-docs.yml +0 -0
  16. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/slack.yml +0 -0
  17. {uipath-2.1.21 → uipath-2.1.22}/.github/workflows/test.yml +0 -0
  18. {uipath-2.1.21 → uipath-2.1.22}/.gitignore +0 -0
  19. {uipath-2.1.21 → uipath-2.1.22}/.pre-commit-config.yaml +0 -0
  20. {uipath-2.1.21 → uipath-2.1.22}/.python-version +0 -0
  21. {uipath-2.1.21 → uipath-2.1.22}/.vscode/extensions.json +0 -0
  22. {uipath-2.1.21 → uipath-2.1.22}/.vscode/launch.json +0 -0
  23. {uipath-2.1.21 → uipath-2.1.22}/.vscode/settings.json +0 -0
  24. {uipath-2.1.21 → uipath-2.1.22}/CONTRIBUTING.md +0 -0
  25. {uipath-2.1.21 → uipath-2.1.22}/LICENSE +0 -0
  26. {uipath-2.1.21 → uipath-2.1.22}/README.md +0 -0
  27. {uipath-2.1.21 → uipath-2.1.22}/docs/CONTRIBUTING.md +0 -0
  28. {uipath-2.1.21 → uipath-2.1.22}/docs/FAQ.md +0 -0
  29. {uipath-2.1.21 → uipath-2.1.22}/docs/assets/env-preparation-failed-dark.png +0 -0
  30. {uipath-2.1.21 → uipath-2.1.22}/docs/assets/env-preparation-failed-light.png +0 -0
  31. {uipath-2.1.21 → uipath-2.1.22}/docs/assets/favicon.png +0 -0
  32. {uipath-2.1.21 → uipath-2.1.22}/docs/assets/logo-dark.svg +0 -0
  33. {uipath-2.1.21 → uipath-2.1.22}/docs/assets/logo-light.svg +0 -0
  34. {uipath-2.1.21 → uipath-2.1.22}/docs/cli/index.md +0 -0
  35. {uipath-2.1.21 → uipath-2.1.22}/docs/core/actions.md +0 -0
  36. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets/cloud_env_var_dark.gif +0 -0
  37. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets/cloud_env_var_light.gif +0 -0
  38. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
  39. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
  40. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets/copy_path_dark.png +0 -0
  41. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets/copy_path_light.png +0 -0
  42. {uipath-2.1.21 → uipath-2.1.22}/docs/core/assets.md +0 -0
  43. {uipath-2.1.21 → uipath-2.1.22}/docs/core/attachments.md +0 -0
  44. {uipath-2.1.21 → uipath-2.1.22}/docs/core/buckets.md +0 -0
  45. {uipath-2.1.21 → uipath-2.1.22}/docs/core/connections.md +0 -0
  46. {uipath-2.1.21 → uipath-2.1.22}/docs/core/context_grounding.md +0 -0
  47. {uipath-2.1.21 → uipath-2.1.22}/docs/core/environment_variables.md +0 -0
  48. {uipath-2.1.21 → uipath-2.1.22}/docs/core/getting_started.md +0 -0
  49. {uipath-2.1.21 → uipath-2.1.22}/docs/core/jobs.md +0 -0
  50. {uipath-2.1.21 → uipath-2.1.22}/docs/core/llm_gateway.md +0 -0
  51. {uipath-2.1.21 → uipath-2.1.22}/docs/core/processes.md +0 -0
  52. {uipath-2.1.21 → uipath-2.1.22}/docs/core/queues.md +0 -0
  53. {uipath-2.1.21 → uipath-2.1.22}/docs/core/traced.md +0 -0
  54. {uipath-2.1.21 → uipath-2.1.22}/docs/hooks.py +0 -0
  55. {uipath-2.1.21 → uipath-2.1.22}/docs/index.md +0 -0
  56. {uipath-2.1.21 → uipath-2.1.22}/docs/javascripts/extra.js +0 -0
  57. {uipath-2.1.21 → uipath-2.1.22}/docs/overrides/main.html +0 -0
  58. {uipath-2.1.21 → uipath-2.1.22}/docs/overrides/partials/actions.html +0 -0
  59. {uipath-2.1.21 → uipath-2.1.22}/docs/overrides/partials/logo.html +0 -0
  60. {uipath-2.1.21 → uipath-2.1.22}/docs/release_policy.md +0 -0
  61. {uipath-2.1.21 → uipath-2.1.22}/docs/sample_images/google-ADK-agent/agent-output.png +0 -0
  62. {uipath-2.1.21 → uipath-2.1.22}/docs/stylesheets/extra.css +0 -0
  63. {uipath-2.1.21 → uipath-2.1.22}/justfile +0 -0
  64. {uipath-2.1.21 → uipath-2.1.22}/mkdocs.yml +0 -0
  65. {uipath-2.1.21 → uipath-2.1.22}/py.typed +0 -0
  66. {uipath-2.1.21 → uipath-2.1.22}/samples/event-trigger/.python-version +0 -0
  67. {uipath-2.1.21 → uipath-2.1.22}/samples/event-trigger/README.md +0 -0
  68. {uipath-2.1.21 → uipath-2.1.22}/samples/event-trigger/main.py +0 -0
  69. {uipath-2.1.21 → uipath-2.1.22}/samples/event-trigger/pyproject.toml +0 -0
  70. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/.env.example +0 -0
  71. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/README.md +0 -0
  72. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/input.json +0 -0
  73. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/multi_tool_agent/__init__.py +0 -0
  74. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/multi_tool_agent/agent.py +0 -0
  75. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/pyproject.toml +0 -0
  76. {uipath-2.1.21 → uipath-2.1.22}/samples/google-ADK-agent/uv.lock +0 -0
  77. {uipath-2.1.21 → uipath-2.1.22}/scripts/debug_test.py +0 -0
  78. {uipath-2.1.21 → uipath-2.1.22}/scripts/lint_httpx_client.py +0 -0
  79. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/__init__.py +0 -0
  80. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/README.md +0 -0
  81. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/__init__.py +0 -0
  82. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/_auth_server.py +0 -0
  83. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/_client_credentials.py +0 -0
  84. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/_models.py +0 -0
  85. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
  86. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/_portal_service.py +0 -0
  87. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/_utils.py +0 -0
  88. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/auth_config.json +0 -0
  89. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/index.html +0 -0
  90. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/localhost.crt +0 -0
  91. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_auth/localhost.key +0 -0
  92. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/__init__.py +0 -0
  93. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_deterministic_evaluator_base.py +0 -0
  94. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_evaluator_base.py +0 -0
  95. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_evaluator_factory.py +0 -0
  96. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_exact_match_evaluator.py +0 -0
  97. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_json_similarity_evaluator.py +0 -0
  98. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_llm_as_judge_evaluator.py +0 -0
  99. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_evaluators/_trajectory_evaluator.py +0 -0
  100. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_models/__init__.py +0 -0
  101. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_models/_evaluation_set.py +0 -0
  102. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/_models/_evaluators.py +0 -0
  103. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/evaluation_service.py +0 -0
  104. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_evals/progress_reporter.py +0 -0
  105. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_runtime/_contracts.py +0 -0
  106. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_runtime/_escalation.py +0 -0
  107. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_runtime/_hitl.py +0 -0
  108. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_runtime/_logging.py +0 -0
  109. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_runtime/_runtime.py +0 -0
  110. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
  111. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_templates/.rels.template +0 -0
  112. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
  113. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_templates/main.py.template +0 -0
  114. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
  115. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_common.py +0 -0
  116. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_console.py +0 -0
  117. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_constants.py +0 -0
  118. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_debug.py +0 -0
  119. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_folders.py +0 -0
  120. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_input_args.py +0 -0
  121. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
  122. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_processes.py +0 -0
  123. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_project_files.py +0 -0
  124. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_tracing.py +0 -0
  125. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/_utils/_uv_helpers.py +0 -0
  126. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_auth.py +0 -0
  127. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_deploy.py +0 -0
  128. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_eval.py +0 -0
  129. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_init.py +0 -0
  130. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_invoke.py +0 -0
  131. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_new.py +0 -0
  132. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_pack.py +0 -0
  133. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_publish.py +0 -0
  134. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_pull.py +0 -0
  135. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_push.py +0 -0
  136. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/cli_run.py +0 -0
  137. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/middlewares.py +0 -0
  138. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_cli/spinner.py +0 -0
  139. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_config.py +0 -0
  140. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_execution_context.py +0 -0
  141. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_folder_context.py +0 -0
  142. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/__init__.py +0 -0
  143. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/_base_service.py +0 -0
  144. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/actions_service.py +0 -0
  145. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/api_client.py +0 -0
  146. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/assets_service.py +0 -0
  147. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/attachments_service.py +0 -0
  148. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/buckets_service.py +0 -0
  149. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/connections_service.py +0 -0
  150. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/context_grounding_service.py +0 -0
  151. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/folder_service.py +0 -0
  152. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/jobs_service.py +0 -0
  153. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/llm_gateway_service.py +0 -0
  154. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/processes_service.py +0 -0
  155. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_services/queues_service.py +0 -0
  156. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_uipath.py +0 -0
  157. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/__init__.py +0 -0
  158. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_endpoint.py +0 -0
  159. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_infer_bindings.py +0 -0
  160. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_logs.py +0 -0
  161. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_read_overwrites.py +0 -0
  162. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_request_override.py +0 -0
  163. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_request_spec.py +0 -0
  164. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_ssl_context.py +0 -0
  165. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_url.py +0 -0
  166. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/_user_agent.py +0 -0
  167. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/_utils/constants.py +0 -0
  168. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/__init__.py +0 -0
  169. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/action_schema.py +0 -0
  170. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/actions.py +0 -0
  171. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/assets.py +0 -0
  172. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/attachment.py +0 -0
  173. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/buckets.py +0 -0
  174. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/connections.py +0 -0
  175. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/context_grounding.py +0 -0
  176. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/context_grounding_index.py +0 -0
  177. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/errors.py +0 -0
  178. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/exceptions.py +0 -0
  179. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/interrupt_models.py +0 -0
  180. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/job.py +0 -0
  181. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/llm_gateway.py +0 -0
  182. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/processes.py +0 -0
  183. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/models/queues.py +0 -0
  184. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/py.typed +0 -0
  185. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/telemetry/__init__.py +0 -0
  186. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/telemetry/_constants.py +0 -0
  187. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/telemetry/_track.py +0 -0
  188. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/tracing/__init__.py +0 -0
  189. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/tracing/_otel_exporters.py +0 -0
  190. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/tracing/_traced.py +0 -0
  191. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/tracing/_utils.py +0 -0
  192. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/utils/__init__.py +0 -0
  193. {uipath-2.1.21 → uipath-2.1.22}/src/uipath/utils/_endpoints_manager.py +0 -0
  194. {uipath-2.1.21 → uipath-2.1.22}/tests/__init__.py +0 -0
  195. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/conftest.py +0 -0
  196. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/evaluators/test_json_similarity_evaluator.py +0 -0
  197. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/mocks/bindings_script.py +0 -0
  198. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/mocks/pyproject.toml +0 -0
  199. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/mocks/simple_script.py +0 -0
  200. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/mocks/uipath-mock.json +0 -0
  201. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
  202. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_hitl.py +0 -0
  203. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_init.py +0 -0
  204. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_input_args.py +0 -0
  205. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_invoke.py +0 -0
  206. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_new.py +0 -0
  207. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_pack.py +0 -0
  208. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_publish.py +0 -0
  209. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_pull.py +0 -0
  210. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_run.py +0 -0
  211. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/test_utils.py +0 -0
  212. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/utils/common.py +0 -0
  213. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/utils/project_details.py +0 -0
  214. {uipath-2.1.21 → uipath-2.1.22}/tests/cli/utils/uipath_json.py +0 -0
  215. {uipath-2.1.21 → uipath-2.1.22}/tests/conftest.py +0 -0
  216. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/conftest.py +0 -0
  217. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_actions_service.py +0 -0
  218. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_api_client.py +0 -0
  219. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_assets_service.py +0 -0
  220. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_attachments_service.py +0 -0
  221. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_base_service.py +0 -0
  222. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_buckets_service.py +0 -0
  223. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_connections_service.py +0 -0
  224. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_context_grounding_service.py +0 -0
  225. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_folder_service.py +0 -0
  226. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_jobs_service.py +0 -0
  227. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_llm_integration.py +0 -0
  228. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_llm_schema_cleanup.py +0 -0
  229. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_llm_service.py +0 -0
  230. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_processes_service.py +0 -0
  231. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_queues_service.py +0 -0
  232. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
  233. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/test_bindings_inference.py +0 -0
  234. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/test_config.py +0 -0
  235. {uipath-2.1.21 → uipath-2.1.22}/tests/sdk/test_overwrites.py +0 -0
  236. {uipath-2.1.21 → uipath-2.1.22}/tests/tracing/test_otel_exporters.py +0 -0
  237. {uipath-2.1.21 → uipath-2.1.22}/tests/tracing/test_span_utils.py +0 -0
  238. {uipath-2.1.21 → uipath-2.1.22}/tests/tracing/test_traced.py +0 -0
  239. {uipath-2.1.21 → uipath-2.1.22}/tests/tracing/test_tracing_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath
3
- Version: 2.1.21
3
+ Version: 2.1.22
4
4
  Summary: Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools.
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "uipath"
3
- version = "2.1.21"
3
+ version = "2.1.22"
4
4
  description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
5
5
  readme = { file = "README.md", content-type = "text/markdown" }
6
6
  requires-python = ">=3.10"
@@ -133,12 +133,14 @@ class SwFileHandler:
133
133
  self,
134
134
  local_files: list[FileInfo],
135
135
  source_code_files: Dict[str, ProjectFile],
136
+ root_files: Dict[str, ProjectFile],
136
137
  ) -> None:
137
138
  """Process all file uploads to the source_code folder.
138
139
 
139
140
  Args:
140
141
  local_files: List of files to upload
141
142
  source_code_files: Dictionary of existing remote files
143
+ root_files: Dictionary of existing root-level files
142
144
 
143
145
  Returns:
144
146
  Set of processed file names
@@ -186,13 +188,25 @@ class SwFileHandler:
186
188
  )
187
189
  )
188
190
  self.console.info(
189
- f"Uploading {click.style(local_file.file_name, fg='cyan')}"
191
+ f"Uploading {click.style(local_file.relative_path, fg='cyan')}"
190
192
  )
191
193
 
192
194
  # identify and add deleted files
193
195
  structural_migration.deleted_resources.extend(
194
196
  self._collect_deleted_files(source_code_files, processed_source_files)
195
197
  )
198
+
199
+ with open(os.path.join(self.directory, "uipath.json"), "r") as f:
200
+ uipath_config = json.load(f)
201
+
202
+ await self._prepare_agent_json_migration(
203
+ structural_migration, root_files, uipath_config
204
+ )
205
+
206
+ await self._prepare_entrypoints_json_migration(
207
+ structural_migration, root_files, uipath_config
208
+ )
209
+
196
210
  await self._studio_client.perform_structural_migration_async(
197
211
  structural_migration
198
212
  )
@@ -303,40 +317,65 @@ class SwFileHandler:
303
317
 
304
318
  return True
305
319
 
306
- async def _update_agent_json(
320
+ async def _prepare_entrypoints_json_migration(
307
321
  self,
308
- agent_json_file: Optional[ProjectFile] = None,
322
+ structural_migration: StructuralMigration,
323
+ root_files: Dict[str, ProjectFile],
324
+ uipath_config: Dict[str, Any],
309
325
  ) -> None:
310
- """Update agent.json file with metadata from uipath.json.
326
+ """Prepare entry-points.json to be included in the same structural migration."""
327
+ existing = root_files.get("entry-points.json")
328
+ if existing:
329
+ try:
330
+ entry_points_json = (
331
+ await self._studio_client.download_file_async(existing.id)
332
+ ).json()
333
+ entry_points_json["entryPoints"] = uipath_config["entryPoints"]
311
334
 
312
- This function:
313
- 1. Downloads existing agent.json if it exists
314
- 2. Updates metadata based on uipath.json content
315
- 3. Increments code version
316
- 4. Updates author from JWT or pyproject.toml
317
- 5. Uploads updated agent.json
335
+ except Exception:
336
+ self.console.warning(
337
+ "Could not parse existing entry-points.json file, using default version"
338
+ )
339
+ structural_migration.modified_resources.append(
340
+ ModifiedResource(
341
+ id=existing.id,
342
+ content_string=json.dumps(entry_points_json),
343
+ )
344
+ )
345
+ self.console.info(
346
+ f"Updating {click.style('entry-points.json', fg='yellow')}"
347
+ )
318
348
 
319
- Args:
320
- agent_json_file: Optional existing agent.json file
349
+ else:
350
+ self.console.warning(
351
+ "'entry-points.json' file does not exist in Studio Web project, initializing using default version"
352
+ )
353
+ entry_points_json = {
354
+ "$schema": "https://cloud.uipath.com/draft/2024-12/entry-point",
355
+ "$id": "entry-points.json",
356
+ "entryPoints": uipath_config["entryPoints"],
357
+ }
358
+ structural_migration.added_resources.append(
359
+ AddedResource(
360
+ file_name="entry-points.json",
361
+ content_string=json.dumps(entry_points_json),
362
+ )
363
+ )
364
+ self.console.info(
365
+ f"Uploading {click.style('entry-points.json', fg='cyan')}"
366
+ )
321
367
 
322
- Raises:
323
- httpx.HTTPError: If API requests fail
324
- FileNotFoundError: If required files are missing
325
- json.JSONDecodeError: If JSON parsing fails
326
- """
368
+ async def _prepare_agent_json_migration(
369
+ self,
370
+ structural_migration: StructuralMigration,
371
+ root_files: Dict[str, ProjectFile],
372
+ uipath_config: Dict[str, Any],
373
+ ) -> None:
374
+ """Prepare agent.json to be included in the same structural migration."""
327
375
 
328
376
  def get_author_from_token_or_toml() -> str:
329
377
  import jwt
330
378
 
331
- """Extract preferred_username from JWT token or fall back to pyproject.toml author.
332
-
333
- Args:
334
- directory: Project directory containing pyproject.toml
335
-
336
- Returns:
337
- str: Author name from JWT preferred_username or pyproject.toml authors field
338
- """
339
- # Try to get author from JWT token first
340
379
  token = os.getenv("UIPATH_ACCESS_TOKEN")
341
380
  if token:
342
381
  try:
@@ -350,19 +389,15 @@ class SwFileHandler:
350
389
  # If JWT decoding fails, fall back to toml
351
390
  pass
352
391
 
353
- toml_data = read_toml_project(os.path.join(directory, "pyproject.toml"))
354
-
392
+ toml_data = read_toml_project(
393
+ os.path.join(self.directory, "pyproject.toml")
394
+ )
355
395
  return toml_data.get("authors", "").strip()
356
396
 
357
- # Read uipath.json
358
- directory = os.getcwd()
359
- with open(os.path.join(directory, "uipath.json"), "r") as f:
360
- uipath_config = json.load(f)
361
-
362
397
  try:
363
398
  entrypoints = [
364
- {"input": entry_point["input"], "output": entry_point["output"]}
365
- for entry_point in uipath_config["entryPoints"]
399
+ {"input": entrypoint["input"], "output": entrypoint["output"]}
400
+ for entrypoint in uipath_config["entryPoints"]
366
401
  ]
367
402
  except (FileNotFoundError, KeyError) as e:
368
403
  self.console.error(
@@ -388,14 +423,12 @@ class SwFileHandler:
388
423
  ),
389
424
  }
390
425
 
391
- if agent_json_file:
392
- # Download existing agent.json
393
- existing_agent_json = (
394
- await self._studio_client.download_file_async(agent_json_file.id)
395
- ).json()
396
-
426
+ existing = root_files.get("agent.json")
427
+ if existing:
397
428
  try:
398
- # Get current version and increment patch version
429
+ existing_agent_json = (
430
+ await self._studio_client.download_file_async(existing.id)
431
+ ).json()
399
432
  version_parts = existing_agent_json["metadata"]["codeVersion"].split(
400
433
  "."
401
434
  )
@@ -403,20 +436,32 @@ class SwFileHandler:
403
436
  version_parts[-1] = str(int(version_parts[-1]) + 1)
404
437
  agent_json["metadata"]["codeVersion"] = ".".join(version_parts)
405
438
  else:
406
- # If version format is invalid, start from initial version + 1
407
439
  agent_json["metadata"]["codeVersion"] = (
408
440
  AGENT_INITIAL_CODE_VERSION[:-1] + "1"
409
441
  )
410
- except (json.JSONDecodeError, KeyError, ValueError):
442
+ except Exception:
411
443
  self.console.warning(
412
- "Could not parse existing agent.json, using default version"
444
+ "Could not parse existing agent.json file, using default version"
413
445
  )
414
- file, action = await self._studio_client.upload_file_async(
415
- file_content=json.dumps(agent_json),
416
- file_name="agent.json",
417
- remote_file=agent_json_file,
418
- )
419
- self.console.success(f"{action} {click.style('agent.json', fg='cyan')}")
446
+
447
+ structural_migration.modified_resources.append(
448
+ ModifiedResource(
449
+ id=existing.id,
450
+ content_string=json.dumps(agent_json),
451
+ )
452
+ )
453
+ self.console.info(f"Updating {click.style('agent.json', fg='yellow')}")
454
+ else:
455
+ self.console.warning(
456
+ "'agent.json' file does not exist in Studio Web project, initializing using default version"
457
+ )
458
+ structural_migration.added_resources.append(
459
+ AddedResource(
460
+ file_name="agent.json",
461
+ content_string=json.dumps(agent_json),
462
+ )
463
+ )
464
+ self.console.info(f"Uploading {click.style('agent.json', fg='cyan')}")
420
465
 
421
466
  async def upload_source_files(self, config_data: dict[str, Any]) -> None:
422
467
  """Main method to upload source files to the UiPath project.
@@ -457,8 +502,4 @@ class SwFileHandler:
457
502
  self.include_uv_lock,
458
503
  directories_to_ignore=["evals"],
459
504
  )
460
- await self._process_file_uploads(files, source_code_files)
461
-
462
- await self._update_agent_json(
463
- root_files.get("agent.json", None),
464
- )
505
+ await self._process_file_uploads(files, source_code_files, root_files)
@@ -175,13 +175,20 @@ def get_folder_by_name(
175
175
 
176
176
 
177
177
  class AddedResource(BaseModel):
178
- content_file_path: str
178
+ """Represents a new file to be added during a structural migration."""
179
+
180
+ content_file_path: Optional[str] = None
179
181
  parent_path: Optional[str] = None
182
+ file_name: Optional[str] = None
183
+ content_string: Optional[str] = None
180
184
 
181
185
 
182
186
  class ModifiedResource(BaseModel):
187
+ """Represents a file update during a structural migration."""
188
+
183
189
  id: str
184
- content_file_path: str
190
+ content_file_path: Optional[str] = None
191
+ content_string: Optional[str] = None
185
192
 
186
193
 
187
194
  class StructuralMigration(BaseModel):
@@ -336,6 +343,53 @@ class StudioClient:
336
343
  headers=headers or {},
337
344
  )
338
345
 
346
+ def _resolve_content_and_filename(
347
+ self,
348
+ *,
349
+ content_string: Optional[str],
350
+ content_file_path: Optional[str],
351
+ file_name: Optional[str] = None,
352
+ modified: bool = False,
353
+ ) -> tuple[bytes, Optional[str]]:
354
+ """Resolve multipart content bytes and filename for a resource.
355
+
356
+ Args:
357
+ content_string: Inline content as a string.
358
+ content_file_path: Path to a local file to read if inline content is not provided.
359
+ file_name: Explicit filename to use when adding a new resource.
360
+
361
+ Returns:
362
+ A tuple of (content_bytes, filename).
363
+
364
+ Raises:
365
+ FileNotFoundError: If a provided file path does not exist.
366
+ ValueError: If a filename cannot be determined.
367
+ """
368
+ content_bytes: bytes = b""
369
+ resolved_name: Optional[str] = None
370
+ if content_string is not None:
371
+ content_bytes = content_string.encode("utf-8")
372
+ elif content_file_path:
373
+ if os.path.exists(content_file_path):
374
+ with open(content_file_path, "rb") as f:
375
+ content_bytes = f.read()
376
+ else:
377
+ raise FileNotFoundError(f"File not found: {content_file_path}")
378
+
379
+ if file_name:
380
+ resolved_name = file_name
381
+ elif content_file_path:
382
+ resolved_name = os.path.basename(content_file_path)
383
+ elif not modified:
384
+ raise ValueError(
385
+ "Unable to determine filename for multipart upload. "
386
+ "When providing inline content (content_string), you must also provide file_name. "
387
+ "Alternatively, set content_file_path so the filename can be inferred. "
388
+ f"Received file_name={file_name!r}, content_file_path={content_file_path!r}."
389
+ )
390
+
391
+ return content_bytes, resolved_name
392
+
339
393
  @with_lock_retry
340
394
  async def perform_structural_migration_async(
341
395
  self,
@@ -360,44 +414,37 @@ class StudioClient:
360
414
  (None, deleted_resources_json),
361
415
  )
362
416
  )
363
-
364
417
  for i, added_resource in enumerate(structural_migration.added_resources):
365
- if os.path.exists(added_resource.content_file_path):
366
- with open(added_resource.content_file_path, "rb") as f:
367
- content = f.read()
368
-
369
- filename = os.path.basename(added_resource.content_file_path)
370
- files.append((f"AddedResources[{i}].Content", (filename, content)))
371
-
372
- if added_resource.parent_path:
373
- files.append(
374
- (
375
- f"AddedResources[{i}].ParentPath",
376
- (None, added_resource.parent_path),
377
- )
378
- )
379
- else:
380
- raise FileNotFoundError(
381
- f"File not found: {added_resource.content_file_path}"
382
- )
418
+ content_bytes, filename = self._resolve_content_and_filename(
419
+ content_string=added_resource.content_string,
420
+ content_file_path=added_resource.content_file_path,
421
+ file_name=added_resource.file_name,
422
+ )
383
423
 
384
- for i, modified_resource in enumerate(structural_migration.modified_resources):
385
- if os.path.exists(modified_resource.content_file_path):
386
- with open(modified_resource.content_file_path, "rb") as f:
387
- content = f.read()
424
+ files.append((f"AddedResources[{i}].Content", (filename, content_bytes)))
388
425
 
389
- filename = os.path.basename(modified_resource.content_file_path)
390
- files.append((f"ModifiedResources[{i}].Content", (filename, content)))
426
+ if added_resource.parent_path:
391
427
  files.append(
392
428
  (
393
- f"ModifiedResources[{i}].Id",
394
- (None, modified_resource.id),
429
+ f"AddedResources[{i}].ParentPath",
430
+ (None, added_resource.parent_path),
395
431
  )
396
432
  )
397
- else:
398
- raise FileNotFoundError(
399
- f"File not found: {modified_resource.content_file_path}"
433
+
434
+ for i, modified_resource in enumerate(structural_migration.modified_resources):
435
+ content_bytes, _ = self._resolve_content_and_filename(
436
+ content_string=modified_resource.content_string,
437
+ content_file_path=modified_resource.content_file_path,
438
+ modified=True,
439
+ )
440
+
441
+ files.append((f"ModifiedResources[{i}].Content", content_bytes))
442
+ files.append(
443
+ (
444
+ f"ModifiedResources[{i}].Id",
445
+ (None, modified_resource.id),
400
446
  )
447
+ )
401
448
 
402
449
  response = await self.uipath.api_client.request_async(
403
450
  "POST",
@@ -14,33 +14,78 @@ from tests.cli.utils.common import configure_env_vars
14
14
  from uipath._cli.cli_push import push
15
15
 
16
16
 
17
- def extract_agent_json_file_from_request(request: Request) -> dict[Any, str]:
18
- boundary = re.search(rb"--([a-f0-9]+)", request.content).group(1).decode()
19
- parts = request.content.split(f"--{boundary}".encode())
20
-
21
- # Locate the agent.json file
22
- agent_json_part = None
17
+ def extract_agent_json_from_modified_resources(
18
+ request: Request, *, agent_file_id: str | None = None
19
+ ) -> dict[str, Any]:
20
+ """Extract agent.json content from ModifiedResources in StructuralMigration payload."""
21
+ match = re.search(
22
+ rb"boundary=([-._0-9A-Za-z]+)", request.headers.get("Content-Type", "").encode()
23
+ )
24
+ if match is None:
25
+ # Fallback to body sniffing like older helper
26
+ match = re.search(rb"--([-._0-9A-Za-z]+)", request.content)
27
+ assert match is not None, "Could not detect multipart boundary"
28
+ boundary = match.group(1)
29
+ parts = request.content.split(b"--" + boundary)
30
+
31
+ # Require agent_file_id and search only ModifiedResources
32
+ assert agent_file_id is not None, (
33
+ "agent_file_id is required to extract agent.json from ModifiedResources"
34
+ )
35
+ target_index: str | None = None
23
36
  for part in parts:
24
37
  if (
25
- b'Content-Disposition: form-data; name="file"; filename="agent.json"'
26
- in part
38
+ b"Content-Disposition: form-data;" in part
39
+ and b"ModifiedResources[" in part
40
+ and b"].Id" in part
27
41
  ):
28
- agent_json_part = part
29
- break
42
+ body = part.split(b"\r\n\r\n", 1)
43
+ if len(body) == 2:
44
+ value = body[1].strip().strip(b"\r\n")
45
+ if value.decode(errors="ignore") == agent_file_id:
46
+ m = re.search(rb"ModifiedResources\[(\d+)\]\.Id", part)
47
+ if m:
48
+ target_index = m.group(1).decode()
49
+ break
50
+
51
+ if target_index is not None:
52
+ for part in parts:
53
+ if (
54
+ b"Content-Disposition: form-data;" in part
55
+ and f"ModifiedResources[{target_index}].Content".encode() in part
56
+ ):
57
+ content_bytes = part.split(b"\r\n\r\n", 1)[1].split(b"\r\n")[0]
58
+ return json.loads(content_bytes.decode())
30
59
 
31
- assert agent_json_part is not None, (
32
- "agent.json part not found in the multipart/form-data payload."
60
+ raise AssertionError(
61
+ "agent.json content not found in ModifiedResources of StructuralMigration payload"
33
62
  )
34
63
 
35
- # Extract the agent.json content
36
- agent_json_content = (
37
- agent_json_part.split(b"\r\n\r\n", 1)[1].split(b"\r\n--")[0].decode()
64
+
65
+ def extract_agent_json_from_added_resources(request: Request) -> dict[str, Any]:
66
+ """Extract agent.json content from AddedResources in StructuralMigration payload."""
67
+ match = re.search(
68
+ rb"boundary=([-._0-9A-Za-z]+)", request.headers.get("Content-Type", "").encode()
38
69
  )
70
+ if match is None:
71
+ match = re.search(rb"--([-._0-9A-Za-z]+)", request.content)
72
+ assert match is not None, "Could not detect multipart boundary"
73
+ boundary = match.group(1)
74
+ parts = request.content.split(b"--" + boundary)
39
75
 
40
- # Parse the agent.json payload
41
- agent_json_data = json.loads(agent_json_content)
76
+ for part in parts:
77
+ if (
78
+ b"Content-Disposition: form-data;" in part
79
+ and b"AddedResources[" in part
80
+ and b"].Content" in part
81
+ and b'filename="agent.json"' in part
82
+ ):
83
+ content_bytes = part.split(b"\r\n\r\n", 1)[1].split(b"\r\n")[0]
84
+ return json.loads(content_bytes.decode())
42
85
 
43
- return agent_json_data
86
+ raise AssertionError(
87
+ "agent.json content not found in AddedResources of StructuralMigration payload"
88
+ )
44
89
 
45
90
 
46
91
  class TestPush:
@@ -144,6 +189,14 @@ class TestPush:
144
189
  "isEntryPoint": False,
145
190
  "ignoredFromPublish": False,
146
191
  },
192
+ {
193
+ "id": "898",
194
+ "name": "entry-points.json",
195
+ "isMain": False,
196
+ "fileType": "1",
197
+ "isEntryPoint": False,
198
+ "ignoredFromPublish": False,
199
+ },
147
200
  ],
148
201
  "folderType": "0",
149
202
  }
@@ -153,7 +206,7 @@ class TestPush:
153
206
  json=mock_structure,
154
207
  )
155
208
 
156
- self._mock_lock_retrieval(httpx_mock, base_url, project_id, times=2)
209
+ self._mock_lock_retrieval(httpx_mock, base_url, project_id, times=1)
157
210
 
158
211
  # Mock agent.json download
159
212
  httpx_mock.add_response(
@@ -163,6 +216,14 @@ class TestPush:
163
216
  json={"metadata": {"codeVersion": "0.1.0"}},
164
217
  )
165
218
 
219
+ # Mock entry-points.json download
220
+ httpx_mock.add_response(
221
+ method="GET",
222
+ url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/File/898",
223
+ status_code=200,
224
+ json={"entryPoints": {}},
225
+ )
226
+
166
227
  httpx_mock.add_response(
167
228
  method="POST",
168
229
  url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/StructuralMigration",
@@ -176,14 +237,6 @@ class TestPush:
176
237
  json=mock_structure,
177
238
  )
178
239
 
179
- # For agent.json
180
- httpx_mock.add_response(
181
- method="PUT",
182
- url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/File/246",
183
- status_code=200,
184
- json={},
185
- )
186
-
187
240
  with runner.isolated_filesystem(temp_dir=temp_dir):
188
241
  # Create necessary files
189
242
  with open("uipath.json", "w") as f:
@@ -209,19 +262,17 @@ class TestPush:
209
262
  assert "Updating pyproject.toml" in result.output
210
263
  assert "Updating uipath.json" in result.output
211
264
  assert "Uploading uv.lock" in result.output
212
- assert "Updated agent.json" in result.output
213
-
214
- # check incremented code version
215
- agent_upload_request = None
216
- for request in httpx_mock.get_requests(
217
- method="PUT",
218
- url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/File/246",
219
- ):
220
- agent_upload_request = request
221
- break
265
+ assert "Updating agent.json" in result.output
266
+ assert "Updating entry-points.json" in result.output
222
267
 
223
- agent_json_content = extract_agent_json_file_from_request(
224
- agent_upload_request
268
+ # check incremented code version via StructuralMigration payload
269
+ structural_migration_request = httpx_mock.get_request(
270
+ method="POST",
271
+ url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/StructuralMigration",
272
+ )
273
+ assert structural_migration_request is not None
274
+ agent_json_content = extract_agent_json_from_modified_resources(
275
+ structural_migration_request, agent_file_id="246"
225
276
  )
226
277
 
227
278
  # Validate `metadata["codeVersion"]`
@@ -272,7 +323,7 @@ class TestPush:
272
323
  json=mock_structure,
273
324
  )
274
325
 
275
- self._mock_lock_retrieval(httpx_mock, base_url, project_id, times=3)
326
+ self._mock_lock_retrieval(httpx_mock, base_url, project_id, times=2)
276
327
 
277
328
  httpx_mock.add_response(
278
329
  method="POST",
@@ -287,13 +338,6 @@ class TestPush:
287
338
  json=mock_structure,
288
339
  )
289
340
 
290
- httpx_mock.add_response(
291
- method="POST",
292
- url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/File",
293
- status_code=200,
294
- json={},
295
- )
296
-
297
341
  with runner.isolated_filesystem(temp_dir=temp_dir):
298
342
  # Create necessary files
299
343
  with open("uipath.json", "w") as f:
@@ -319,23 +363,17 @@ class TestPush:
319
363
  assert "Uploading pyproject.toml" in result.output
320
364
  assert "Uploading uipath.json" in result.output
321
365
  assert "Uploading uv.lock" in result.output
322
- assert "Uploaded agent.json" in result.output
366
+ assert "Uploading agent.json" in result.output
367
+ assert "Uploading entry-points.json" in result.output
323
368
 
324
369
  # check expected agent.json fields
325
- agent_upload_request = None
326
- for request in httpx_mock.get_requests(
370
+ structural_migration_request = httpx_mock.get_request(
327
371
  method="POST",
328
- url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/File",
329
- ):
330
- if (
331
- b'Content-Disposition: form-data; name="file"; filename="agent.json"'
332
- in request.content
333
- ):
334
- agent_upload_request = request
335
- break
336
-
337
- agent_json_content = extract_agent_json_file_from_request(
338
- agent_upload_request
372
+ url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/StructuralMigration",
373
+ )
374
+ assert structural_migration_request is not None
375
+ agent_json_content = extract_agent_json_from_added_resources(
376
+ structural_migration_request
339
377
  )
340
378
 
341
379
  expected_code_version = "1.0.0"
@@ -446,7 +484,7 @@ class TestPush:
446
484
  json=mock_structure,
447
485
  )
448
486
 
449
- self._mock_lock_retrieval(httpx_mock, base_url, project_id, times=2)
487
+ self._mock_lock_retrieval(httpx_mock, base_url, project_id, times=1)
450
488
 
451
489
  httpx_mock.add_response(
452
490
  method="POST",
@@ -461,13 +499,6 @@ class TestPush:
461
499
  json=mock_structure,
462
500
  )
463
501
 
464
- httpx_mock.add_response(
465
- method="POST",
466
- url=f"{base_url}/studio_/backend/api/Project/{project_id}/FileOperations/File",
467
- status_code=200,
468
- json={},
469
- )
470
-
471
502
  with runner.isolated_filesystem(temp_dir=temp_dir):
472
503
  # Create necessary files
473
504
  with open("uipath.json", "w") as f:
@@ -2029,7 +2029,7 @@ wheels = [
2029
2029
 
2030
2030
  [[package]]
2031
2031
  name = "uipath"
2032
- version = "2.1.21"
2032
+ version = "2.1.22"
2033
2033
  source = { editable = "." }
2034
2034
  dependencies = [
2035
2035
  { name = "azure-monitor-opentelemetry" },
File without changes
File without changes
File without changes