uipath 2.1.5__tar.gz → 2.1.6__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 (216) hide show
  1. {uipath-2.1.5 → uipath-2.1.6}/PKG-INFO +1 -1
  2. {uipath-2.1.5 → uipath-2.1.6}/pyproject.toml +1 -1
  3. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/llm_gateway_service.py +149 -13
  4. uipath-2.1.6/tests/sdk/services/test_llm_schema_cleanup.py +232 -0
  5. uipath-2.1.6/tests/sdk/services/test_llm_service.py +290 -0
  6. {uipath-2.1.5 → uipath-2.1.6}/uv.lock +846 -845
  7. uipath-2.1.5/tests/sdk/services/test_llm_service.py +0 -83
  8. {uipath-2.1.5 → uipath-2.1.6}/.cursorrules +0 -0
  9. {uipath-2.1.5 → uipath-2.1.6}/.editorconfig +0 -0
  10. {uipath-2.1.5 → uipath-2.1.6}/.gitattributes +0 -0
  11. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/cd.yml +0 -0
  12. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/ci.yml +0 -0
  13. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/commitlint.yml +0 -0
  14. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/lint.yml +0 -0
  15. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/publish-dev.yml +0 -0
  16. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/publish-docs.yml +0 -0
  17. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/slack.yml +0 -0
  18. {uipath-2.1.5 → uipath-2.1.6}/.github/workflows/test.yml +0 -0
  19. {uipath-2.1.5 → uipath-2.1.6}/.gitignore +0 -0
  20. {uipath-2.1.5 → uipath-2.1.6}/.pre-commit-config.yaml +0 -0
  21. {uipath-2.1.5 → uipath-2.1.6}/.python-version +0 -0
  22. {uipath-2.1.5 → uipath-2.1.6}/.vscode/extensions.json +0 -0
  23. {uipath-2.1.5 → uipath-2.1.6}/.vscode/launch.json +0 -0
  24. {uipath-2.1.5 → uipath-2.1.6}/.vscode/settings.json +0 -0
  25. {uipath-2.1.5 → uipath-2.1.6}/CONTRIBUTING.md +0 -0
  26. {uipath-2.1.5 → uipath-2.1.6}/LICENSE +0 -0
  27. {uipath-2.1.5 → uipath-2.1.6}/README.md +0 -0
  28. {uipath-2.1.5 → uipath-2.1.6}/docs/CONTRIBUTING.md +0 -0
  29. {uipath-2.1.5 → uipath-2.1.6}/docs/FAQ.md +0 -0
  30. {uipath-2.1.5 → uipath-2.1.6}/docs/assets/env-preparation-failed-dark.png +0 -0
  31. {uipath-2.1.5 → uipath-2.1.6}/docs/assets/env-preparation-failed-light.png +0 -0
  32. {uipath-2.1.5 → uipath-2.1.6}/docs/assets/favicon.png +0 -0
  33. {uipath-2.1.5 → uipath-2.1.6}/docs/assets/logo-dark.svg +0 -0
  34. {uipath-2.1.5 → uipath-2.1.6}/docs/assets/logo-light.svg +0 -0
  35. {uipath-2.1.5 → uipath-2.1.6}/docs/cli/index.md +0 -0
  36. {uipath-2.1.5 → uipath-2.1.6}/docs/core/actions.md +0 -0
  37. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets/cloud_env_var_dark.gif +0 -0
  38. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets/cloud_env_var_light.gif +0 -0
  39. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
  40. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
  41. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets/copy_path_dark.png +0 -0
  42. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets/copy_path_light.png +0 -0
  43. {uipath-2.1.5 → uipath-2.1.6}/docs/core/assets.md +0 -0
  44. {uipath-2.1.5 → uipath-2.1.6}/docs/core/attachments.md +0 -0
  45. {uipath-2.1.5 → uipath-2.1.6}/docs/core/buckets.md +0 -0
  46. {uipath-2.1.5 → uipath-2.1.6}/docs/core/connections.md +0 -0
  47. {uipath-2.1.5 → uipath-2.1.6}/docs/core/context_grounding.md +0 -0
  48. {uipath-2.1.5 → uipath-2.1.6}/docs/core/environment_variables.md +0 -0
  49. {uipath-2.1.5 → uipath-2.1.6}/docs/core/getting_started.md +0 -0
  50. {uipath-2.1.5 → uipath-2.1.6}/docs/core/jobs.md +0 -0
  51. {uipath-2.1.5 → uipath-2.1.6}/docs/core/llm_gateway.md +0 -0
  52. {uipath-2.1.5 → uipath-2.1.6}/docs/core/processes.md +0 -0
  53. {uipath-2.1.5 → uipath-2.1.6}/docs/core/queues.md +0 -0
  54. {uipath-2.1.5 → uipath-2.1.6}/docs/core/traced.md +0 -0
  55. {uipath-2.1.5 → uipath-2.1.6}/docs/hooks.py +0 -0
  56. {uipath-2.1.5 → uipath-2.1.6}/docs/index.md +0 -0
  57. {uipath-2.1.5 → uipath-2.1.6}/docs/javascripts/extra.js +0 -0
  58. {uipath-2.1.5 → uipath-2.1.6}/docs/overrides/main.html +0 -0
  59. {uipath-2.1.5 → uipath-2.1.6}/docs/overrides/partials/actions.html +0 -0
  60. {uipath-2.1.5 → uipath-2.1.6}/docs/overrides/partials/logo.html +0 -0
  61. {uipath-2.1.5 → uipath-2.1.6}/docs/release_policy.md +0 -0
  62. {uipath-2.1.5 → uipath-2.1.6}/docs/sample_images/google-ADK-agent/agent-output.png +0 -0
  63. {uipath-2.1.5 → uipath-2.1.6}/docs/stylesheets/extra.css +0 -0
  64. {uipath-2.1.5 → uipath-2.1.6}/justfile +0 -0
  65. {uipath-2.1.5 → uipath-2.1.6}/mkdocs.yml +0 -0
  66. {uipath-2.1.5 → uipath-2.1.6}/py.typed +0 -0
  67. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/.env.example +0 -0
  68. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/README.md +0 -0
  69. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/input.json +0 -0
  70. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/multi_tool_agent/__init__.py +0 -0
  71. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/multi_tool_agent/agent.py +0 -0
  72. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/pyproject.toml +0 -0
  73. {uipath-2.1.5 → uipath-2.1.6}/samples/google-ADK-agent/uv.lock +0 -0
  74. {uipath-2.1.5 → uipath-2.1.6}/scripts/debug_test.py +0 -0
  75. {uipath-2.1.5 → uipath-2.1.6}/scripts/lint_httpx_client.py +0 -0
  76. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/__init__.py +0 -0
  77. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/README.md +0 -0
  78. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/__init__.py +0 -0
  79. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/_auth_server.py +0 -0
  80. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/_client_credentials.py +0 -0
  81. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/_models.py +0 -0
  82. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
  83. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/_portal_service.py +0 -0
  84. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/_utils.py +0 -0
  85. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/auth_config.json +0 -0
  86. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/index.html +0 -0
  87. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/localhost.crt +0 -0
  88. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_auth/localhost.key +0 -0
  89. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_runtime/_contracts.py +0 -0
  90. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_runtime/_escalation.py +0 -0
  91. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_runtime/_hitl.py +0 -0
  92. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_runtime/_logging.py +0 -0
  93. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_runtime/_runtime.py +0 -0
  94. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
  95. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_templates/.rels.template +0 -0
  96. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
  97. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_templates/main.py.template +0 -0
  98. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
  99. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_common.py +0 -0
  100. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_console.py +0 -0
  101. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_constants.py +0 -0
  102. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_debug.py +0 -0
  103. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_folders.py +0 -0
  104. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_input_args.py +0 -0
  105. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
  106. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_processes.py +0 -0
  107. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_project_files.py +0 -0
  108. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_studio_project.py +0 -0
  109. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_tracing.py +0 -0
  110. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/_utils/_uv_helpers.py +0 -0
  111. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_auth.py +0 -0
  112. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_deploy.py +0 -0
  113. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_init.py +0 -0
  114. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_invoke.py +0 -0
  115. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_new.py +0 -0
  116. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_pack.py +0 -0
  117. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_publish.py +0 -0
  118. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_push.py +0 -0
  119. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/cli_run.py +0 -0
  120. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/middlewares.py +0 -0
  121. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_cli/spinner.py +0 -0
  122. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_config.py +0 -0
  123. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_execution_context.py +0 -0
  124. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_folder_context.py +0 -0
  125. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/__init__.py +0 -0
  126. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/_base_service.py +0 -0
  127. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/actions_service.py +0 -0
  128. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/api_client.py +0 -0
  129. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/assets_service.py +0 -0
  130. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/attachments_service.py +0 -0
  131. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/buckets_service.py +0 -0
  132. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/connections_service.py +0 -0
  133. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/context_grounding_service.py +0 -0
  134. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/folder_service.py +0 -0
  135. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/jobs_service.py +0 -0
  136. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/processes_service.py +0 -0
  137. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_services/queues_service.py +0 -0
  138. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_uipath.py +0 -0
  139. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/__init__.py +0 -0
  140. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_endpoint.py +0 -0
  141. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_infer_bindings.py +0 -0
  142. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_logs.py +0 -0
  143. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_read_overwrites.py +0 -0
  144. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_request_override.py +0 -0
  145. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_request_spec.py +0 -0
  146. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_ssl_context.py +0 -0
  147. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_url.py +0 -0
  148. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/_user_agent.py +0 -0
  149. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/_utils/constants.py +0 -0
  150. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/__init__.py +0 -0
  151. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/action_schema.py +0 -0
  152. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/actions.py +0 -0
  153. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/assets.py +0 -0
  154. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/attachment.py +0 -0
  155. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/buckets.py +0 -0
  156. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/connections.py +0 -0
  157. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/context_grounding.py +0 -0
  158. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/context_grounding_index.py +0 -0
  159. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/errors.py +0 -0
  160. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/exceptions.py +0 -0
  161. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/interrupt_models.py +0 -0
  162. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/job.py +0 -0
  163. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/llm_gateway.py +0 -0
  164. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/processes.py +0 -0
  165. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/models/queues.py +0 -0
  166. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/py.typed +0 -0
  167. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/telemetry/__init__.py +0 -0
  168. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/telemetry/_constants.py +0 -0
  169. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/telemetry/_track.py +0 -0
  170. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/tracing/__init__.py +0 -0
  171. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/tracing/_otel_exporters.py +0 -0
  172. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/tracing/_traced.py +0 -0
  173. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/tracing/_utils.py +0 -0
  174. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/utils/__init__.py +0 -0
  175. {uipath-2.1.5 → uipath-2.1.6}/src/uipath/utils/_endpoints_manager.py +0 -0
  176. {uipath-2.1.5 → uipath-2.1.6}/tests/__init__.py +0 -0
  177. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/conftest.py +0 -0
  178. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/mocks/bindings_script.py +0 -0
  179. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/mocks/pyproject.toml +0 -0
  180. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/mocks/simple_script.py +0 -0
  181. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/mocks/uipath-mock.json +0 -0
  182. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
  183. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_hitl.py +0 -0
  184. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_init.py +0 -0
  185. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_invoke.py +0 -0
  186. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_new.py +0 -0
  187. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_pack.py +0 -0
  188. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_publish.py +0 -0
  189. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_push.py +0 -0
  190. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_run.py +0 -0
  191. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/test_utils.py +0 -0
  192. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/utils/project_details.py +0 -0
  193. {uipath-2.1.5 → uipath-2.1.6}/tests/cli/utils/uipath_json.py +0 -0
  194. {uipath-2.1.5 → uipath-2.1.6}/tests/conftest.py +0 -0
  195. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/conftest.py +0 -0
  196. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_actions_service.py +0 -0
  197. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_api_client.py +0 -0
  198. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_assets_service.py +0 -0
  199. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_attachments_service.py +0 -0
  200. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_base_service.py +0 -0
  201. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_buckets_service.py +0 -0
  202. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_connections_service.py +0 -0
  203. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_context_grounding_service.py +0 -0
  204. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_folder_service.py +0 -0
  205. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_jobs_service.py +0 -0
  206. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_llm_integration.py +0 -0
  207. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_processes_service.py +0 -0
  208. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_queues_service.py +0 -0
  209. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
  210. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/test_bindings_inference.py +0 -0
  211. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/test_config.py +0 -0
  212. {uipath-2.1.5 → uipath-2.1.6}/tests/sdk/test_overwrites.py +0 -0
  213. {uipath-2.1.5 → uipath-2.1.6}/tests/tracing/test_otel_exporters.py +0 -0
  214. {uipath-2.1.5 → uipath-2.1.6}/tests/tracing/test_span_utils.py +0 -0
  215. {uipath-2.1.5 → uipath-2.1.6}/tests/tracing/test_traced.py +0 -0
  216. {uipath-2.1.5 → uipath-2.1.6}/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.5
3
+ Version: 2.1.6
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.5"
3
+ version = "2.1.6"
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"
@@ -17,7 +17,9 @@ Classes:
17
17
  """
18
18
 
19
19
  import json
20
- from typing import Any, Dict, List, Optional
20
+ from typing import Any, Dict, List, Optional, Union
21
+
22
+ from pydantic import BaseModel
21
23
 
22
24
  from .._config import Config
23
25
  from .._execution_context import ExecutionContext
@@ -76,6 +78,67 @@ class EmbeddingModels(object):
76
78
  text_embedding_ada_002 = "text-embedding-ada-002"
77
79
 
78
80
 
81
+ def _cleanup_schema(model_class: type[BaseModel]) -> Dict[str, Any]:
82
+ """Clean up a Pydantic model schema for use with LLM Gateway.
83
+
84
+ This function converts a Pydantic model's JSON schema to a format that's
85
+ compatible with the LLM Gateway's JSON schema requirements by removing
86
+ titles and other metadata that might cause validation issues.
87
+
88
+ Args:
89
+ model_class (type[BaseModel]): A Pydantic BaseModel class to convert to schema.
90
+
91
+ Returns:
92
+ dict: A cleaned JSON schema dictionary suitable for LLM Gateway response_format.
93
+
94
+ Examples:
95
+ ```python
96
+ from pydantic import BaseModel
97
+ from typing import List
98
+
99
+ class Country(BaseModel):
100
+ name: str
101
+ capital: str
102
+ languages: List[str]
103
+
104
+ schema = _cleanup_schema(Country)
105
+ # Returns a clean schema without titles and unnecessary metadata
106
+ ```
107
+ """
108
+ schema = model_class.model_json_schema()
109
+
110
+ def clean_properties(properties):
111
+ """Clean property definitions by removing titles and cleaning nested items."""
112
+ cleaned_props = {}
113
+ for prop_name, prop_def in properties.items():
114
+ if isinstance(prop_def, dict):
115
+ cleaned_prop = {}
116
+ for key, value in prop_def.items():
117
+ if key == "title": # Skip title
118
+ continue
119
+ elif key == "items" and isinstance(value, dict):
120
+ # Clean nested items
121
+ cleaned_items = {}
122
+ for item_key, item_value in value.items():
123
+ if item_key != "title":
124
+ cleaned_items[item_key] = item_value
125
+ cleaned_prop[key] = cleaned_items
126
+ else:
127
+ cleaned_prop[key] = value
128
+ cleaned_props[prop_name] = cleaned_prop
129
+ return cleaned_props
130
+
131
+ # Create clean schema
132
+ clean_schema = {
133
+ "type": "object",
134
+ "properties": clean_properties(schema.get("properties", {})),
135
+ "required": schema.get("required", []),
136
+ "additionalProperties": False,
137
+ }
138
+
139
+ return clean_schema
140
+
141
+
79
142
  class UiPathOpenAIService(BaseService):
80
143
  """Service for calling UiPath's LLM Gateway using OpenAI-compatible API.
81
144
 
@@ -146,7 +209,7 @@ class UiPathOpenAIService(BaseService):
146
209
  model: str = ChatModels.gpt_4o_mini_2024_07_18,
147
210
  max_tokens: int = 50,
148
211
  temperature: float = 0,
149
- response_format: Optional[Dict[str, Any]] = None,
212
+ response_format: Optional[Union[Dict[str, Any], type[BaseModel]]] = None,
150
213
  api_version: str = API_VERSION,
151
214
  ):
152
215
  """Generate chat completions using UiPath's LLM Gateway service.
@@ -168,9 +231,11 @@ class UiPathOpenAIService(BaseService):
168
231
  temperature (float, optional): Temperature for sampling, between 0 and 1.
169
232
  Lower values (closer to 0) make output more deterministic and focused,
170
233
  higher values make it more creative and random. Defaults to 0.
171
- response_format (Optional[Dict[str, Any]], optional): An object specifying the format
172
- that the model must output. Used to enable JSON mode or other structured outputs.
173
- Defaults to None.
234
+ response_format (Optional[Union[Dict[str, Any], type[BaseModel]]], optional):
235
+ An object specifying the format that the model must output. Can be either:
236
+ - A dictionary with response format configuration (traditional format)
237
+ - A Pydantic BaseModel class (automatically converted to JSON schema)
238
+ Used to enable JSON mode or other structured outputs. Defaults to None.
174
239
  api_version (str, optional): The API version to use. Defaults to API_VERSION.
175
240
 
176
241
  Returns:
@@ -198,11 +263,31 @@ class UiPathOpenAIService(BaseService):
198
263
  max_tokens=200,
199
264
  temperature=0.3
200
265
  )
266
+
267
+ # Using Pydantic model for structured response
268
+ from pydantic import BaseModel
269
+ from typing import List
270
+
271
+ class Country(BaseModel):
272
+ name: str
273
+ capital: str
274
+ languages: List[str]
275
+
276
+ response = await service.chat_completions(
277
+ messages=[
278
+ {"role": "system", "content": "You are a helpful assistant. Respond with structured JSON."},
279
+ {"role": "user", "content": "Tell me about Canada."}
280
+ ],
281
+ response_format=Country, # Pass BaseModel directly
282
+ max_tokens=1000
283
+ )
201
284
  ```
202
285
 
203
286
  Note:
204
287
  The conversation history can be included to provide context to the model.
205
288
  Each message should have both 'role' and 'content' keys.
289
+ When using a Pydantic BaseModel as response_format, it will be automatically
290
+ converted to the appropriate JSON schema format for the LLM Gateway.
206
291
  """
207
292
  endpoint = EndpointManager.get_passthrough_endpoint().format(
208
293
  model=model, api_version=api_version
@@ -215,9 +300,24 @@ class UiPathOpenAIService(BaseService):
215
300
  "temperature": temperature,
216
301
  }
217
302
 
218
- # Add response_format if provided
303
+ # Handle response_format - convert BaseModel to schema if needed
219
304
  if response_format:
220
- request_body["response_format"] = response_format
305
+ if isinstance(response_format, type) and issubclass(
306
+ response_format, BaseModel
307
+ ):
308
+ # Convert Pydantic model to JSON schema format
309
+ cleaned_schema = _cleanup_schema(response_format)
310
+ request_body["response_format"] = {
311
+ "type": "json_schema",
312
+ "json_schema": {
313
+ "name": response_format.__name__.lower(),
314
+ "strict": True,
315
+ "schema": cleaned_schema,
316
+ },
317
+ }
318
+ else:
319
+ # Use provided dictionary format directly
320
+ request_body["response_format"] = response_format
221
321
 
222
322
  response = await self.request_async(
223
323
  "POST",
@@ -258,7 +358,7 @@ class UiPathLlmChatService(BaseService):
258
358
  top_p: float = 1,
259
359
  tools: Optional[List[ToolDefinition]] = None,
260
360
  tool_choice: Optional[ToolChoice] = None,
261
- response_format: Optional[Dict[str, Any]] = None,
361
+ response_format: Optional[Union[Dict[str, Any], type[BaseModel]]] = None,
262
362
  api_version: str = NORMALIZED_API_VERSION,
263
363
  ):
264
364
  """Generate chat completions using UiPath's normalized LLM Gateway API.
@@ -295,9 +395,11 @@ class UiPathLlmChatService(BaseService):
295
395
  tool_choice (Optional[ToolChoice], optional): Controls which tools the model can call.
296
396
  Can be "auto" (model decides), "none" (no tools), or a specific tool choice.
297
397
  Defaults to None.
298
- response_format (Optional[Dict[str, Any]], optional): An object specifying the format
299
- that the model must output. Used to enable JSON mode or other structured outputs.
300
- Defaults to None.
398
+ response_format (Optional[Union[Dict[str, Any], type[BaseModel]]], optional):
399
+ An object specifying the format that the model must output. Can be either:
400
+ - A dictionary with response format configuration (traditional format)
401
+ - A Pydantic BaseModel class (automatically converted to JSON schema)
402
+ Used to enable JSON mode or other structured outputs. Defaults to None.
301
403
  api_version (str, optional): The normalized API version to use.
302
404
  Defaults to NORMALIZED_API_VERSION.
303
405
 
@@ -349,6 +451,25 @@ class UiPathLlmChatService(BaseService):
349
451
  presence_penalty=0.2,
350
452
  n=3 # Generate 3 alternative responses
351
453
  )
454
+
455
+ # Using Pydantic model for structured response
456
+ from pydantic import BaseModel
457
+ from typing import List
458
+
459
+ class Country(BaseModel):
460
+ name: str
461
+ capital: str
462
+ languages: List[str]
463
+
464
+ response = await service.chat_completions(
465
+ messages=[
466
+ {"role": "system", "content": "You are a helpful assistant. Respond with structured JSON."},
467
+ {"role": "user", "content": "Tell me about Canada."}
468
+ ],
469
+ response_format=Country, # Pass BaseModel directly
470
+ max_tokens=1000
471
+ )
472
+ )
352
473
  ```
353
474
 
354
475
  Note:
@@ -370,9 +491,24 @@ class UiPathLlmChatService(BaseService):
370
491
  "top_p": top_p,
371
492
  }
372
493
 
373
- # Add response_format if provided
494
+ # Handle response_format - convert BaseModel to schema if needed
374
495
  if response_format:
375
- request_body["response_format"] = response_format
496
+ if isinstance(response_format, type) and issubclass(
497
+ response_format, BaseModel
498
+ ):
499
+ # Convert Pydantic model to JSON schema format
500
+ cleaned_schema = _cleanup_schema(response_format)
501
+ request_body["response_format"] = {
502
+ "type": "json_schema",
503
+ "json_schema": {
504
+ "name": response_format.__name__.lower(),
505
+ "strict": True,
506
+ "schema": cleaned_schema,
507
+ },
508
+ }
509
+ else:
510
+ # Use provided dictionary format directly
511
+ request_body["response_format"] = response_format
376
512
 
377
513
  # Add tools if provided - convert to UiPath format
378
514
  if tools:
@@ -0,0 +1,232 @@
1
+ """Tests for the _cleanup_schema function in LLM Gateway Service."""
2
+
3
+ from typing import List, Optional
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from uipath._services.llm_gateway_service import _cleanup_schema
8
+
9
+
10
+ # Simple test models
11
+ class SimpleModel(BaseModel):
12
+ name: str
13
+ age: int
14
+ active: bool
15
+
16
+
17
+ class ModelWithList(BaseModel):
18
+ names: List[str]
19
+ numbers: List[int]
20
+
21
+
22
+ class ModelWithOptional(BaseModel):
23
+ required_field: str
24
+ optional_field: Optional[str] = None
25
+
26
+
27
+ # Complex nested models for comprehensive testing
28
+ class Task(BaseModel):
29
+ task_id: int
30
+ description: str
31
+ completed: bool
32
+
33
+
34
+ class Project(BaseModel):
35
+ project_id: int
36
+ name: str
37
+ tasks: List[Task]
38
+
39
+
40
+ class Team(BaseModel):
41
+ team_id: int
42
+ team_name: str
43
+ members: List[str]
44
+ projects: List[Project]
45
+
46
+
47
+ class Department(BaseModel):
48
+ department_id: int
49
+ department_name: str
50
+ teams: List[Team]
51
+
52
+
53
+ class Company(BaseModel):
54
+ company_id: int
55
+ company_name: str
56
+ departments: List[Department]
57
+
58
+
59
+ class TestCleanupSchema:
60
+ """Test cases for the _cleanup_schema function."""
61
+
62
+ def test_simple_model_cleanup(self):
63
+ """Test cleanup of a simple model without nested structures."""
64
+ schema = _cleanup_schema(SimpleModel)
65
+
66
+ assert schema["type"] == "object"
67
+ assert schema["additionalProperties"] is False
68
+ assert "required" in schema
69
+ assert set(schema["required"]) == {"name", "age", "active"}
70
+
71
+ # Check properties are cleaned (no titles)
72
+ properties = schema["properties"]
73
+ assert "name" in properties
74
+ assert "age" in properties
75
+ assert "active" in properties
76
+
77
+ # Ensure no 'title' fields are present
78
+ for _prop_name, prop_def in properties.items():
79
+ assert "title" not in prop_def
80
+
81
+ def test_model_with_list_cleanup(self):
82
+ """Test cleanup of a model with list fields."""
83
+ schema = _cleanup_schema(ModelWithList)
84
+
85
+ assert schema["type"] == "object"
86
+ assert schema["additionalProperties"] is False
87
+
88
+ # Check list properties
89
+ names_prop = schema["properties"]["names"]
90
+ assert names_prop["type"] == "array"
91
+ assert "items" in names_prop
92
+ assert names_prop["items"]["type"] == "string"
93
+ # Ensure no 'title' in items
94
+ assert "title" not in names_prop["items"]
95
+
96
+ numbers_prop = schema["properties"]["numbers"]
97
+ assert numbers_prop["type"] == "array"
98
+ assert "items" in numbers_prop
99
+ assert numbers_prop["items"]["type"] == "integer"
100
+ assert "title" not in numbers_prop["items"]
101
+
102
+ def test_model_with_optional_cleanup(self):
103
+ """Test cleanup of a model with optional fields."""
104
+ schema = _cleanup_schema(ModelWithOptional)
105
+
106
+ assert schema["type"] == "object"
107
+ assert schema["additionalProperties"] is False
108
+
109
+ # Only required_field should be in required array
110
+ assert schema["required"] == ["required_field"]
111
+
112
+ # Both fields should be in properties
113
+ assert "required_field" in schema["properties"]
114
+ assert "optional_field" in schema["properties"]
115
+
116
+ def test_complex_nested_model_cleanup(self):
117
+ """Test cleanup of the complex nested Company model."""
118
+ schema = _cleanup_schema(Company)
119
+
120
+ assert schema["type"] == "object"
121
+ assert schema["additionalProperties"] is False
122
+ assert set(schema["required"]) == {"company_id", "company_name", "departments"}
123
+
124
+ # Check top-level properties
125
+ properties = schema["properties"]
126
+ assert "company_id" in properties
127
+ assert "company_name" in properties
128
+ assert "departments" in properties
129
+
130
+ # Check departments is array of objects
131
+ departments_prop = properties["departments"]
132
+ assert departments_prop["type"] == "array"
133
+ assert "items" in departments_prop
134
+ assert "title" not in departments_prop["items"]
135
+
136
+ # Verify no 'title' fields exist anywhere in the schema
137
+ self._assert_no_titles_recursive(schema)
138
+
139
+ def test_schema_structure_integrity(self):
140
+ """Test that the cleaned schema maintains proper JSON Schema structure."""
141
+ schema = _cleanup_schema(Company)
142
+
143
+ # Must have these top-level keys
144
+ required_keys = {"type", "properties", "required", "additionalProperties"}
145
+ assert all(key in schema for key in required_keys)
146
+
147
+ # Type must be object
148
+ assert schema["type"] == "object"
149
+
150
+ # additionalProperties must be False
151
+ assert schema["additionalProperties"] is False
152
+
153
+ # Properties must be a dict
154
+ assert isinstance(schema["properties"], dict)
155
+
156
+ # Required must be a list
157
+ assert isinstance(schema["required"], list)
158
+
159
+ def test_email_field_handling(self):
160
+ """Test that EmailStr fields are properly handled."""
161
+ schema = _cleanup_schema(Team)
162
+
163
+ members_prop = schema["properties"]["members"]
164
+ assert members_prop["type"] == "array"
165
+
166
+ # EmailStr should be treated as string with format
167
+ items = members_prop["items"]
168
+ assert items["type"] == "string"
169
+ # Email format might be present
170
+ if "format" in items:
171
+ assert items["format"] == "email"
172
+
173
+ def test_nested_objects_cleanup(self):
174
+ """Test that nested objects are properly cleaned."""
175
+ schema = _cleanup_schema(Department)
176
+
177
+ # Check teams property (array of Team objects)
178
+ teams_prop = schema["properties"]["teams"]
179
+ assert teams_prop["type"] == "array"
180
+ assert "items" in teams_prop
181
+
182
+ # The items should not have title
183
+ team_items = teams_prop["items"]
184
+ assert "title" not in team_items
185
+
186
+ # If it's a nested object, check its properties
187
+ if "properties" in team_items:
188
+ for _prop_name, prop_def in team_items["properties"].items():
189
+ assert "title" not in prop_def
190
+
191
+ def _assert_no_titles_recursive(self, obj):
192
+ """Recursively assert that no 'title' fields exist in the schema."""
193
+ if isinstance(obj, dict):
194
+ assert "title" not in obj, f"Found 'title' field in: {obj}"
195
+ for value in obj.values():
196
+ self._assert_no_titles_recursive(value)
197
+ elif isinstance(obj, list):
198
+ for item in obj:
199
+ self._assert_no_titles_recursive(item)
200
+
201
+ def test_function_returns_dict(self):
202
+ """Test that the function returns a dictionary."""
203
+ result = _cleanup_schema(SimpleModel)
204
+ assert isinstance(result, dict)
205
+
206
+ def test_function_with_inheritance(self):
207
+ """Test cleanup with model inheritance."""
208
+
209
+ class BaseEntity(BaseModel):
210
+ id: int
211
+ created_at: str
212
+
213
+ class ExtendedEntity(BaseEntity):
214
+ name: str
215
+ description: Optional[str] = None
216
+
217
+ schema = _cleanup_schema(ExtendedEntity)
218
+
219
+ # Should include fields from both base and derived class
220
+ properties = schema["properties"]
221
+ assert "id" in properties
222
+ assert "created_at" in properties
223
+ assert "name" in properties
224
+ assert "description" in properties
225
+
226
+ # Required fields from both classes
227
+ required_fields = set(schema["required"])
228
+ assert "id" in required_fields
229
+ assert "created_at" in required_fields
230
+ assert "name" in required_fields
231
+ # description is optional, so not in required
232
+ assert "description" not in required_fields