uipath 2.1.17__tar.gz → 2.1.20__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.
- {uipath-2.1.17 → uipath-2.1.20}/PKG-INFO +1 -1
- {uipath-2.1.17 → uipath-2.1.20}/pyproject.toml +1 -1
- uipath-2.1.20/samples/event-trigger/.python-version +1 -0
- uipath-2.1.20/samples/event-trigger/README.md +128 -0
- uipath-2.1.20/samples/event-trigger/main.py +34 -0
- uipath-2.1.20/samples/event-trigger/pyproject.toml +9 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_evaluators/__init__.py +6 -4
- uipath-2.1.20/src/uipath/_cli/_evals/_evaluators/_deterministic_evaluator_base.py +46 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_evaluators/_evaluator_factory.py +42 -22
- uipath-2.1.20/src/uipath/_cli/_evals/_evaluators/_exact_match_evaluator.py +40 -0
- uipath-2.1.20/src/uipath/_cli/_evals/_evaluators/_json_similarity_evaluator.py +168 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_evaluators/_llm_as_judge_evaluator.py +2 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_models/_evaluators.py +11 -10
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/progress_reporter.py +15 -4
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_runtime/_runtime.py +43 -7
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_input_args.py +28 -1
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_parse_ast.py +12 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_project_files.py +7 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/connections_service.py +82 -2
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_infer_bindings.py +5 -2
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/__init__.py +2 -1
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/connections.py +17 -0
- uipath-2.1.20/src/uipath/utils/_endpoints_manager.py +200 -0
- uipath-2.1.20/tests/cli/evaluators/test_json_similarity_evaluator.py +237 -0
- uipath-2.1.20/tests/cli/test_input_args.py +114 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_pack.py +21 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_run.py +86 -0
- uipath-2.1.20/tests/sdk/services/test_connections_service.py +418 -0
- {uipath-2.1.17 → uipath-2.1.20}/uv.lock +1 -1
- uipath-2.1.17/src/uipath/_cli/_evals/_evaluators/_agent_scorer_evaluator.py +0 -48
- uipath-2.1.17/src/uipath/_cli/_evals/_evaluators/_deterministic_evaluator.py +0 -41
- uipath-2.1.17/src/uipath/utils/_endpoints_manager.py +0 -101
- uipath-2.1.17/tests/sdk/services/test_connections_service.py +0 -196
- {uipath-2.1.17 → uipath-2.1.20}/.cursorrules +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.editorconfig +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.gitattributes +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/cd.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/ci.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/commitlint.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/lint.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/publish-dev.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/publish-docs.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/slack.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.github/workflows/test.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.gitignore +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.pre-commit-config.yaml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.python-version +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.vscode/extensions.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.vscode/launch.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/.vscode/settings.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/CONTRIBUTING.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/LICENSE +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/README.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/CONTRIBUTING.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/FAQ.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/assets/env-preparation-failed-dark.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/assets/env-preparation-failed-light.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/assets/favicon.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/assets/logo-dark.svg +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/assets/logo-light.svg +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/cli/index.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/actions.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets/cloud_env_var_dark.gif +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets/cloud_env_var_light.gif +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets/copy_path_dark.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets/copy_path_light.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/assets.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/attachments.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/buckets.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/connections.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/context_grounding.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/environment_variables.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/getting_started.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/jobs.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/llm_gateway.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/processes.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/queues.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/core/traced.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/hooks.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/index.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/javascripts/extra.js +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/overrides/main.html +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/overrides/partials/actions.html +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/overrides/partials/logo.html +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/release_policy.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/sample_images/google-ADK-agent/agent-output.png +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/docs/stylesheets/extra.css +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/justfile +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/mkdocs.yml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/py.typed +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/.env.example +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/README.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/input.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/multi_tool_agent/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/multi_tool_agent/agent.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/pyproject.toml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/samples/google-ADK-agent/uv.lock +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/scripts/debug_test.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/scripts/lint_httpx_client.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/README.md +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/_auth_server.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/_client_credentials.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/_models.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/_portal_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/_utils.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/auth_config.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/index.html +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/localhost.crt +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_auth/localhost.key +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_evaluators/_evaluator_base.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_evaluators/_trajectory_evaluator.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_models/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_models/_evaluation_set.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/evaluation_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_push/sw_file_handler.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_runtime/_contracts.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_runtime/_escalation.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_runtime/_hitl.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_runtime/_logging.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_templates/.rels.template +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_templates/main.py.template +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_common.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_console.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_constants.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_debug.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_folders.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_processes.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_studio_project.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_tracing.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_utils/_uv_helpers.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_auth.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_deploy.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_eval.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_init.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_invoke.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_new.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_pack.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_publish.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_pull.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_push.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/cli_run.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/middlewares.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/spinner.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_config.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_execution_context.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_folder_context.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/_base_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/actions_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/api_client.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/assets_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/attachments_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/buckets_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/context_grounding_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/folder_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/jobs_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/llm_gateway_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/processes_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_services/queues_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_uipath.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_endpoint.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_logs.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_read_overwrites.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_request_override.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_request_spec.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_ssl_context.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_url.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/_user_agent.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/_utils/constants.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/action_schema.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/actions.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/assets.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/attachment.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/buckets.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/context_grounding.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/context_grounding_index.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/errors.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/exceptions.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/interrupt_models.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/job.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/llm_gateway.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/processes.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/models/queues.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/py.typed +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/telemetry/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/telemetry/_constants.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/telemetry/_track.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/tracing/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/tracing/_otel_exporters.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/tracing/_traced.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/tracing/_utils.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/src/uipath/utils/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/__init__.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/conftest.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/mocks/bindings_script.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/mocks/pyproject.toml +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/mocks/simple_script.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/mocks/uipath-mock.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_hitl.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_init.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_invoke.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_new.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_publish.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_pull.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_push.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/test_utils.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/utils/common.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/utils/project_details.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/cli/utils/uipath_json.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/conftest.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/conftest.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_actions_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_api_client.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_assets_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_attachments_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_base_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_buckets_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_context_grounding_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_folder_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_jobs_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_llm_integration.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_llm_schema_cleanup.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_llm_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_processes_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_queues_service.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/test_bindings_inference.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/test_config.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/sdk/test_overwrites.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/tracing/test_otel_exporters.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/tracing/test_span_utils.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/tests/tracing/test_traced.py +0 -0
- {uipath-2.1.17 → uipath-2.1.20}/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.
|
3
|
+
Version: 2.1.20
|
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.
|
3
|
+
version = "2.1.20"
|
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"
|
@@ -0,0 +1 @@
|
|
1
|
+
3.13
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# UiPath Coded Agents with Event Triggers
|
2
|
+
|
3
|
+
This guide explains how to create Python-based UiPath Coded Agents that respond to event triggers, enabling seamless event-driven agents.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
UiPath Coded Agents allow you to write automation logic directly in Python while leveraging UiPath's event trigger system. This project demonstrates how to create agents that handle external events from systems like Gmail, Slack, and other connectors.
|
8
|
+
|
9
|
+
## How to Set Up UiPath Coded Agents with Event Triggers
|
10
|
+
|
11
|
+
### Step 1: Install UiPath Python SDK
|
12
|
+
|
13
|
+
1. Open it with your prefered editor
|
14
|
+
2. In terminal run:
|
15
|
+
```bash
|
16
|
+
uv init
|
17
|
+
uv add uipath
|
18
|
+
uv run uipath new event-agent
|
19
|
+
uv run uipath init
|
20
|
+
```
|
21
|
+
|
22
|
+
### Step 2: Create Your Coded Agent
|
23
|
+
|
24
|
+
Create a Python file with your agent logic using the UiPath SDK:
|
25
|
+
|
26
|
+
```python
|
27
|
+
from dataclasses import dataclass
|
28
|
+
from uipath.models import EventArguments
|
29
|
+
from uipath import UiPath
|
30
|
+
import logging
|
31
|
+
|
32
|
+
logger = logging.getLogger(__name__)
|
33
|
+
|
34
|
+
@dataclass
|
35
|
+
class EchoOut:
|
36
|
+
message: dict
|
37
|
+
|
38
|
+
# use EventArguments when called by UiPath EventTriggers
|
39
|
+
def main(input: EventArguments) -> EchoOut:
|
40
|
+
sdk = UiPath()
|
41
|
+
|
42
|
+
# get the event payload, this will be different from event to event
|
43
|
+
payload = sdk.connections.retrieve_event_payload(input)
|
44
|
+
|
45
|
+
logger.info(f"Received payload: {payload}")
|
46
|
+
|
47
|
+
return EchoOut(payload)
|
48
|
+
```
|
49
|
+
|
50
|
+
Run `uipath init` again to update the input arguments.
|
51
|
+
|
52
|
+
### Step 3: Understanding the Event Flow
|
53
|
+
|
54
|
+
When an event trigger fires, UiPath will:
|
55
|
+
1. Pass event data through `EventArguments`
|
56
|
+
2. Your agent retrieves the full payload using `sdk.connections.retrieve_event_payload(input)`
|
57
|
+
3. Process the payload based on your business logic
|
58
|
+
4. Return structured output
|
59
|
+
|
60
|
+
### Step 4: Publish Your Coded Agent and setup Event Trigger
|
61
|
+
|
62
|
+
#### 4.1: Build and Publish
|
63
|
+
1. Use `uipath pack` and `uipath publish` to create and publish the package
|
64
|
+
2. Create an Orchestrator Automation from the published process
|
65
|
+
|
66
|
+
#### 4.2: Access Event Triggers
|
67
|
+
1. Log into UiPath Orchestrator
|
68
|
+
2. Navigate to **Automations** → **Processes**
|
69
|
+
3. Click on your coded workflow process
|
70
|
+
|
71
|
+
#### 4.3: Create Event Trigger
|
72
|
+
1. Go to the **Triggers** tab
|
73
|
+
2. Click **Add Trigger** → **Event Trigger**
|
74
|
+
|
75
|
+
#### 4.4: Configure Event Trigger Settings
|
76
|
+
1. **Name**: Descriptive name (e.g., "Gmail Event Handler")
|
77
|
+
2. **Event Source**: Select connector type:
|
78
|
+
- `uipath-google-gmailcustom` for Gmail
|
79
|
+
- `uipath-slack` for Slack
|
80
|
+
- `uipath-microsoft-outlookcustom` for Outlook
|
81
|
+
- Custom connectors
|
82
|
+
3. **Event Type**: Choose specific event:
|
83
|
+
- `EMAIL_RECEIVED` for emails
|
84
|
+
- `MESSAGE_RECEIVED` for chat messages
|
85
|
+
- Custom event types
|
86
|
+
4. **Filters**: Optional event filtering criteria
|
87
|
+
|
88
|
+
#### 4.5: Map Event to Input Arguments
|
89
|
+
The event data will automatically be passed to your `EventArguments` parameter.
|
90
|
+
|
91
|
+
#### 4.6: Enable the Trigger
|
92
|
+
1. Review configuration
|
93
|
+
2. Click **Create** to save
|
94
|
+
3. Ensure trigger status is **Enabled**
|
95
|
+
|
96
|
+
### Step 5: Test Your Setup
|
97
|
+
|
98
|
+
#### 5.1: Trigger Test Events
|
99
|
+
- Send test email (Gmail triggers)
|
100
|
+
- Post message in Slack (Slack triggers)
|
101
|
+
- Perform action matching your event source
|
102
|
+
|
103
|
+
#### 5.2: Monitor Execution
|
104
|
+
1. Check **Monitoring** → **Jobs** in Orchestrator
|
105
|
+
2. View job details and execution logs
|
106
|
+
3. Verify your coded agent processed the event correctly
|
107
|
+
|
108
|
+
#### 5.3: Debug with Logs
|
109
|
+
|
110
|
+
```python
|
111
|
+
import logging
|
112
|
+
|
113
|
+
logger = logging.getLogger(__name__)
|
114
|
+
|
115
|
+
def main(input: EventArguments) -> EchoOut:
|
116
|
+
sdk = UiPath()
|
117
|
+
|
118
|
+
# payload will be a json (dict) specific to your event
|
119
|
+
payload = sdk.connections.retrieve_event_payload(input)
|
120
|
+
logger.info(f"Successfully retrieved payload: {type(payload)}")
|
121
|
+
logger.debug(f"Payload details: {payload}")
|
122
|
+
|
123
|
+
# Your processing logic here
|
124
|
+
result = process_event(payload)
|
125
|
+
|
126
|
+
logger.info(f"Event processed successfully: {result}")
|
127
|
+
return EchoOut(result)
|
128
|
+
```
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from uipath.models import EventArguments
|
3
|
+
from uipath import UiPath
|
4
|
+
from uipath.tracing import traced
|
5
|
+
import logging
|
6
|
+
|
7
|
+
logger = logging.getLogger(__name__)
|
8
|
+
|
9
|
+
@dataclass
|
10
|
+
class EchoOut:
|
11
|
+
message: dict
|
12
|
+
|
13
|
+
@traced()
|
14
|
+
def handle_slack_event(payload: dict[str, any]) -> EchoOut:
|
15
|
+
"""Handle Slack message events"""
|
16
|
+
message = payload['event']['text'] if 'event' in payload and 'text' in payload['event'] else "No message"
|
17
|
+
user = payload['event']['user'] if 'event' in payload and 'user' in payload['event'] else "Unknown user"
|
18
|
+
|
19
|
+
logger.info(f"Slack message from {user}: {message}")
|
20
|
+
|
21
|
+
|
22
|
+
# use InputTriggerEventArgs when called by UiPath EventTriggers
|
23
|
+
@traced()
|
24
|
+
def main(input: EventArguments) -> EchoOut:
|
25
|
+
sdk = UiPath()
|
26
|
+
|
27
|
+
# get the event payload, this will be different from event to event
|
28
|
+
payload = sdk.connections.retrieve_event_payload(input)
|
29
|
+
|
30
|
+
handle_slack_event(payload)
|
31
|
+
|
32
|
+
logger.info(f"Received payload: {payload}")
|
33
|
+
|
34
|
+
return EchoOut(payload)
|
@@ -3,18 +3,20 @@
|
|
3
3
|
This package contains all evaluator types and the factory for creating them.
|
4
4
|
"""
|
5
5
|
|
6
|
-
from .
|
7
|
-
from ._deterministic_evaluator import DeterministicEvaluator
|
6
|
+
from ._deterministic_evaluator_base import DeterministicEvaluatorBase
|
8
7
|
from ._evaluator_base import EvaluatorBase
|
9
8
|
from ._evaluator_factory import EvaluatorFactory
|
9
|
+
from ._exact_match_evaluator import ExactMatchEvaluator
|
10
|
+
from ._json_similarity_evaluator import JsonSimilarityEvaluator
|
10
11
|
from ._llm_as_judge_evaluator import LlmAsAJudgeEvaluator
|
11
12
|
from ._trajectory_evaluator import TrajectoryEvaluator
|
12
13
|
|
13
14
|
__all__ = [
|
14
15
|
"EvaluatorBase",
|
16
|
+
"DeterministicEvaluatorBase",
|
15
17
|
"EvaluatorFactory",
|
16
|
-
"
|
18
|
+
"JsonSimilarityEvaluator",
|
19
|
+
"ExactMatchEvaluator",
|
17
20
|
"LlmAsAJudgeEvaluator",
|
18
|
-
"AgentScorerEvaluator",
|
19
21
|
"TrajectoryEvaluator",
|
20
22
|
]
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import copy
|
2
|
+
import json
|
3
|
+
from abc import ABC
|
4
|
+
from typing import Any, Dict, Tuple
|
5
|
+
|
6
|
+
from ._evaluator_base import EvaluatorBase
|
7
|
+
|
8
|
+
|
9
|
+
class DeterministicEvaluatorBase(EvaluatorBase, ABC):
|
10
|
+
def __init__(self, target_output_key: str = "*"):
|
11
|
+
super().__init__()
|
12
|
+
self.target_output_key = target_output_key
|
13
|
+
|
14
|
+
def _select_targets(
|
15
|
+
self, expected_output: Dict[str, Any], actual_output: Dict[str, Any]
|
16
|
+
) -> Tuple[Any, Any]:
|
17
|
+
actual_output_copy = copy.deepcopy(actual_output)
|
18
|
+
expected_output_copy = copy.deepcopy(expected_output)
|
19
|
+
if self.target_output_key != "*":
|
20
|
+
if (
|
21
|
+
self.target_output_key not in actual_output
|
22
|
+
or self.target_output_key not in expected_output
|
23
|
+
):
|
24
|
+
raise ValueError(
|
25
|
+
f"Field '{self.target_output_key}' missing from expected or actual output"
|
26
|
+
)
|
27
|
+
actual_output_copy = actual_output_copy[self.target_output_key]
|
28
|
+
expected_output_copy = expected_output[self.target_output_key]
|
29
|
+
return actual_output_copy, expected_output_copy
|
30
|
+
|
31
|
+
def _canonical_json(self, obj: Any) -> str:
|
32
|
+
return json.dumps(
|
33
|
+
self._normalize_numbers(obj),
|
34
|
+
sort_keys=True,
|
35
|
+
separators=(",", ":"),
|
36
|
+
ensure_ascii=False,
|
37
|
+
)
|
38
|
+
|
39
|
+
def _normalize_numbers(self, obj: Any) -> Any:
|
40
|
+
if isinstance(obj, dict):
|
41
|
+
return {k: self._normalize_numbers(v) for k, v in obj.items()}
|
42
|
+
if isinstance(obj, (list, tuple)):
|
43
|
+
return [self._normalize_numbers(v) for v in obj]
|
44
|
+
if isinstance(obj, (int, float)) and not isinstance(obj, bool):
|
45
|
+
return float(obj)
|
46
|
+
return obj
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from typing import Any, Dict
|
2
2
|
|
3
3
|
from .._models import EvaluatorCategory, EvaluatorType
|
4
|
-
from ._agent_scorer_evaluator import AgentScorerEvaluator
|
5
|
-
from ._deterministic_evaluator import DeterministicEvaluator
|
6
4
|
from ._evaluator_base import EvaluatorBase, EvaluatorBaseParams
|
5
|
+
from ._exact_match_evaluator import ExactMatchEvaluator
|
6
|
+
from ._json_similarity_evaluator import JsonSimilarityEvaluator
|
7
7
|
from ._llm_as_judge_evaluator import LlmAsAJudgeEvaluator
|
8
8
|
from ._trajectory_evaluator import TrajectoryEvaluator
|
9
9
|
|
@@ -50,23 +50,50 @@ class EvaluatorFactory:
|
|
50
50
|
)
|
51
51
|
|
52
52
|
# Create evaluator based on category
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
match category:
|
54
|
+
case EvaluatorCategory.Deterministic:
|
55
|
+
if evaluator_type == evaluator_type.Equals:
|
56
|
+
return EvaluatorFactory._create_exact_match_evaluator(
|
57
|
+
base_params, data
|
58
|
+
)
|
59
|
+
elif evaluator_type == evaluator_type.JsonSimilarity:
|
60
|
+
return EvaluatorFactory._create_json_similarity_evaluator(
|
61
|
+
base_params, data
|
62
|
+
)
|
63
|
+
else:
|
64
|
+
raise ValueError(
|
65
|
+
f"Unknown evaluator type {evaluator_type} for category {category}"
|
66
|
+
)
|
67
|
+
case EvaluatorCategory.LlmAsAJudge:
|
68
|
+
return EvaluatorFactory._create_llm_as_judge_evaluator(
|
69
|
+
base_params, data
|
70
|
+
)
|
71
|
+
case EvaluatorCategory.AgentScorer:
|
72
|
+
raise NotImplementedError()
|
73
|
+
case EvaluatorCategory.Trajectory:
|
74
|
+
return EvaluatorFactory._create_trajectory_evaluator(base_params, data)
|
75
|
+
case _:
|
76
|
+
raise ValueError(f"Unknown evaluator category: {category}")
|
63
77
|
|
64
78
|
@staticmethod
|
65
|
-
def
|
79
|
+
def _create_exact_match_evaluator(
|
66
80
|
base_params: EvaluatorBaseParams, data: Dict[str, Any]
|
67
|
-
) ->
|
81
|
+
) -> ExactMatchEvaluator:
|
68
82
|
"""Create a deterministic evaluator."""
|
69
|
-
|
83
|
+
return ExactMatchEvaluator.from_params(
|
84
|
+
base_params,
|
85
|
+
target_output_key=data.get("targetOutputKey", "*"),
|
86
|
+
)
|
87
|
+
|
88
|
+
@staticmethod
|
89
|
+
def _create_json_similarity_evaluator(
|
90
|
+
base_params: EvaluatorBaseParams, data: Dict[str, Any]
|
91
|
+
) -> JsonSimilarityEvaluator:
|
92
|
+
"""Create a deterministic evaluator."""
|
93
|
+
return JsonSimilarityEvaluator.from_params(
|
94
|
+
base_params,
|
95
|
+
target_output_key=data.get("targetOutputKey", "*"),
|
96
|
+
)
|
70
97
|
|
71
98
|
@staticmethod
|
72
99
|
def _create_llm_as_judge_evaluator(
|
@@ -88,13 +115,6 @@ class EvaluatorFactory:
|
|
88
115
|
target_output_key=data.get("targetOutputKey", "*"),
|
89
116
|
)
|
90
117
|
|
91
|
-
@staticmethod
|
92
|
-
def _create_agent_scorer_evaluator(
|
93
|
-
base_params: EvaluatorBaseParams, data: Dict[str, Any]
|
94
|
-
) -> AgentScorerEvaluator:
|
95
|
-
"""Create an agent scorer evaluator."""
|
96
|
-
raise NotImplementedError()
|
97
|
-
|
98
118
|
@staticmethod
|
99
119
|
def _create_trajectory_evaluator(
|
100
120
|
base_params: EvaluatorBaseParams, data: Dict[str, Any]
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import copy
|
2
|
+
from typing import Any, Dict
|
3
|
+
|
4
|
+
from uipath._cli._evals._evaluators._deterministic_evaluator_base import (
|
5
|
+
DeterministicEvaluatorBase,
|
6
|
+
)
|
7
|
+
from uipath._cli._evals._models import EvaluationResult
|
8
|
+
from uipath._cli._evals._models._evaluators import ScoreType
|
9
|
+
|
10
|
+
|
11
|
+
class ExactMatchEvaluator(DeterministicEvaluatorBase):
|
12
|
+
async def evaluate(
|
13
|
+
self,
|
14
|
+
evaluation_id: str,
|
15
|
+
evaluation_name: str,
|
16
|
+
input_data: Dict[str, Any],
|
17
|
+
expected_output: Dict[str, Any],
|
18
|
+
actual_output: Dict[str, Any],
|
19
|
+
) -> EvaluationResult:
|
20
|
+
actual_output_copy = copy.deepcopy(actual_output)
|
21
|
+
expected_output_copy = copy.deepcopy(expected_output)
|
22
|
+
|
23
|
+
actual_output, expected_output = self._select_targets(
|
24
|
+
expected_output, actual_output
|
25
|
+
)
|
26
|
+
are_equal = self._canonical_json(actual_output) == self._canonical_json(
|
27
|
+
expected_output
|
28
|
+
)
|
29
|
+
|
30
|
+
return EvaluationResult(
|
31
|
+
evaluation_id=evaluation_id,
|
32
|
+
evaluation_name=evaluation_name,
|
33
|
+
evaluator_id=self.id,
|
34
|
+
evaluator_name=self.name,
|
35
|
+
score=are_equal,
|
36
|
+
input=input_data,
|
37
|
+
expected_output=expected_output_copy,
|
38
|
+
actual_output=actual_output_copy,
|
39
|
+
score_type=ScoreType.BOOLEAN,
|
40
|
+
)
|
@@ -0,0 +1,168 @@
|
|
1
|
+
import copy
|
2
|
+
import math
|
3
|
+
from typing import Any, Dict, Tuple
|
4
|
+
|
5
|
+
from uipath._cli._evals._evaluators._deterministic_evaluator_base import (
|
6
|
+
DeterministicEvaluatorBase,
|
7
|
+
)
|
8
|
+
from uipath._cli._evals._models import EvaluationResult
|
9
|
+
from uipath._cli._evals._models._evaluators import ScoreType
|
10
|
+
|
11
|
+
|
12
|
+
class JsonSimilarityEvaluator(DeterministicEvaluatorBase):
|
13
|
+
"""Deterministic evaluator that scores structural JSON similarity.
|
14
|
+
|
15
|
+
Compares expected versus actual JSON-like structures and returns a
|
16
|
+
numerical score in the range [0, 100]. The comparison is token-based
|
17
|
+
and tolerant for numbers and strings (via Levenshtein distance).
|
18
|
+
"""
|
19
|
+
|
20
|
+
async def evaluate(
|
21
|
+
self,
|
22
|
+
evaluation_id: str,
|
23
|
+
evaluation_name: str,
|
24
|
+
input_data: Dict[str, Any],
|
25
|
+
expected_output: Dict[str, Any],
|
26
|
+
actual_output: Dict[str, Any],
|
27
|
+
) -> EvaluationResult:
|
28
|
+
"""Evaluate similarity between expected and actual JSON outputs.
|
29
|
+
|
30
|
+
Args:
|
31
|
+
evaluation_id: Unique identifier for this evaluation run.
|
32
|
+
evaluation_name: Human friendly evaluation name.
|
33
|
+
input_data: Input payload used to produce the outputs.
|
34
|
+
expected_output: Ground-truth JSON structure.
|
35
|
+
actual_output: Produced JSON structure to compare against the ground truth.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
EvaluationResult: Structured result with the numerical similarity score.
|
39
|
+
"""
|
40
|
+
actual_output_copy = copy.deepcopy(actual_output)
|
41
|
+
expected_output_copy = copy.deepcopy(expected_output)
|
42
|
+
|
43
|
+
actual_output, expected_output = self._select_targets(
|
44
|
+
expected_output, actual_output
|
45
|
+
)
|
46
|
+
similarity = self._compare_json(expected_output, actual_output)
|
47
|
+
|
48
|
+
return EvaluationResult(
|
49
|
+
evaluation_id=evaluation_id,
|
50
|
+
evaluation_name=evaluation_name,
|
51
|
+
evaluator_id=self.id,
|
52
|
+
evaluator_name=self.name,
|
53
|
+
score=similarity,
|
54
|
+
input=input_data,
|
55
|
+
expected_output=expected_output_copy,
|
56
|
+
actual_output=actual_output_copy,
|
57
|
+
score_type=ScoreType.NUMERICAL,
|
58
|
+
)
|
59
|
+
|
60
|
+
def _compare_json(self, expected: Any, actual: Any) -> float:
|
61
|
+
matched_leaves, total_leaves = self._compare_tokens(expected, actual)
|
62
|
+
if total_leaves == 0:
|
63
|
+
return 100.0
|
64
|
+
sim = (matched_leaves / total_leaves) * 100.0
|
65
|
+
return max(0.0, min(100.0, sim))
|
66
|
+
|
67
|
+
def _compare_tokens(
|
68
|
+
self, expected_token: Any, actual_token: Any
|
69
|
+
) -> Tuple[float, float]:
|
70
|
+
if self._is_number(expected_token) and self._is_number(actual_token):
|
71
|
+
return self._compare_numbers(float(expected_token), float(actual_token))
|
72
|
+
|
73
|
+
if type(expected_token) is not type(actual_token):
|
74
|
+
return 0.0, self._count_leaves(expected_token)
|
75
|
+
|
76
|
+
if isinstance(expected_token, dict):
|
77
|
+
matched_leaves = total_leaves = 0.0
|
78
|
+
# Only expected keys count
|
79
|
+
for expected_key, expected_value in expected_token.items():
|
80
|
+
if isinstance(actual_token, dict) and expected_key in actual_token:
|
81
|
+
matched, total = self._compare_tokens(
|
82
|
+
expected_value, actual_token[expected_key]
|
83
|
+
)
|
84
|
+
else:
|
85
|
+
matched, total = (0.0, self._count_leaves(expected_value))
|
86
|
+
matched_leaves += matched
|
87
|
+
total_leaves += total
|
88
|
+
return matched_leaves, total_leaves
|
89
|
+
|
90
|
+
if isinstance(expected_token, list):
|
91
|
+
matched_leaves = total_leaves = 0.0
|
92
|
+
common_length = min(len(expected_token), len(actual_token))
|
93
|
+
for index in range(common_length):
|
94
|
+
matched, total = self._compare_tokens(
|
95
|
+
expected_token[index], actual_token[index]
|
96
|
+
)
|
97
|
+
matched_leaves += matched
|
98
|
+
total_leaves += total
|
99
|
+
for index in range(common_length, len(expected_token)):
|
100
|
+
total_leaves += self._count_leaves(expected_token[index])
|
101
|
+
return (matched_leaves, total_leaves)
|
102
|
+
|
103
|
+
if isinstance(expected_token, bool):
|
104
|
+
return (1.0, 1.0) if expected_token == actual_token else (0.0, 1.0)
|
105
|
+
|
106
|
+
if isinstance(expected_token, str):
|
107
|
+
return self._compare_strings(expected_token, actual_token)
|
108
|
+
|
109
|
+
return (1.0, 1.0) if str(expected_token) == str(actual_token) else (0.0, 1.0)
|
110
|
+
|
111
|
+
def _compare_numbers(
|
112
|
+
self, expected_number: float, actual_number: float
|
113
|
+
) -> Tuple[float, float]:
|
114
|
+
total = 1.0
|
115
|
+
if math.isclose(expected_number, 0.0, abs_tol=1e-12):
|
116
|
+
matched = 1.0 if math.isclose(actual_number, 0.0, abs_tol=1e-12) else 0.0
|
117
|
+
else:
|
118
|
+
ratio = abs(expected_number - actual_number) / abs(expected_number)
|
119
|
+
matched = max(0.0, min(1.0, 1.0 - ratio))
|
120
|
+
return matched, total
|
121
|
+
|
122
|
+
def _compare_strings(
|
123
|
+
self, expected_string: str, actual_string: str
|
124
|
+
) -> Tuple[float, float]:
|
125
|
+
total = 1.0
|
126
|
+
if not expected_string and not actual_string:
|
127
|
+
return 1.0, total
|
128
|
+
distance = self._levenshtein(expected_string, actual_string)
|
129
|
+
max_length = max(len(expected_string), len(actual_string))
|
130
|
+
similarity = 1.0 - (distance / max_length) if max_length else 1.0
|
131
|
+
similarity = max(0.0, min(1.0, similarity))
|
132
|
+
return similarity, total
|
133
|
+
|
134
|
+
def _count_leaves(self, token_node: Any) -> float:
|
135
|
+
if isinstance(token_node, dict):
|
136
|
+
return sum(
|
137
|
+
self._count_leaves(child_value) for child_value in token_node.values()
|
138
|
+
)
|
139
|
+
if isinstance(token_node, list):
|
140
|
+
return sum(self._count_leaves(child_value) for child_value in token_node)
|
141
|
+
return 1.0
|
142
|
+
|
143
|
+
def _levenshtein(self, source_text: str, target_text: str) -> int:
|
144
|
+
if not source_text:
|
145
|
+
return len(target_text)
|
146
|
+
if not target_text:
|
147
|
+
return len(source_text)
|
148
|
+
source_len, target_len = len(source_text), len(target_text)
|
149
|
+
distance_matrix = [[0] * (target_len + 1) for _ in range(source_len + 1)]
|
150
|
+
for row_idx in range(source_len + 1):
|
151
|
+
distance_matrix[row_idx][0] = row_idx
|
152
|
+
for col_idx in range(target_len + 1):
|
153
|
+
distance_matrix[0][col_idx] = col_idx
|
154
|
+
for row_idx in range(1, source_len + 1):
|
155
|
+
for col_idx in range(1, target_len + 1):
|
156
|
+
substitution_cost = (
|
157
|
+
0 if source_text[row_idx - 1] == target_text[col_idx - 1] else 1
|
158
|
+
)
|
159
|
+
distance_matrix[row_idx][col_idx] = min(
|
160
|
+
distance_matrix[row_idx - 1][col_idx] + 1, # deletion
|
161
|
+
distance_matrix[row_idx][col_idx - 1] + 1, # insertion
|
162
|
+
distance_matrix[row_idx - 1][col_idx - 1]
|
163
|
+
+ substitution_cost, # substitution
|
164
|
+
)
|
165
|
+
return distance_matrix[source_len][target_len]
|
166
|
+
|
167
|
+
def _is_number(self, value: Any) -> bool:
|
168
|
+
return isinstance(value, (int, float)) and not isinstance(value, bool)
|
{uipath-2.1.17 → uipath-2.1.20}/src/uipath/_cli/_evals/_evaluators/_llm_as_judge_evaluator.py
RENAMED
@@ -11,6 +11,7 @@ from ...._utils.constants import (
|
|
11
11
|
COMMUNITY_agents_SUFFIX,
|
12
12
|
)
|
13
13
|
from .._models import EvaluationResult, LLMResponse
|
14
|
+
from .._models._evaluators import ScoreType
|
14
15
|
from ._evaluator_base import EvaluatorBase
|
15
16
|
|
16
17
|
|
@@ -86,6 +87,7 @@ class LlmAsAJudgeEvaluator(EvaluatorBase):
|
|
86
87
|
expected_output=expected_output,
|
87
88
|
actual_output=actual_output,
|
88
89
|
details=llm_response.justification,
|
90
|
+
score_type=ScoreType.NUMERICAL,
|
89
91
|
)
|
90
92
|
|
91
93
|
def _extract_target_value(self, output: Dict[str, Any]) -> Any:
|
@@ -1,8 +1,8 @@
|
|
1
|
-
from datetime import datetime
|
1
|
+
from datetime import datetime, timezone
|
2
2
|
from enum import IntEnum
|
3
3
|
from typing import Any, Dict, List, Optional
|
4
4
|
|
5
|
-
from pydantic import BaseModel
|
5
|
+
from pydantic import BaseModel
|
6
6
|
|
7
7
|
|
8
8
|
class LLMResponse(BaseModel):
|
@@ -50,6 +50,12 @@ class EvaluatorType(IntEnum):
|
|
50
50
|
raise ValueError(f"{value} is not a valid EvaluatorType value")
|
51
51
|
|
52
52
|
|
53
|
+
class ScoreType(IntEnum):
|
54
|
+
BOOLEAN = 0
|
55
|
+
NUMERICAL = 1
|
56
|
+
ERROR = 2
|
57
|
+
|
58
|
+
|
53
59
|
class EvaluationResult(BaseModel):
|
54
60
|
"""Result of a single evaluation."""
|
55
61
|
|
@@ -57,13 +63,14 @@ class EvaluationResult(BaseModel):
|
|
57
63
|
evaluation_name: str
|
58
64
|
evaluator_id: str
|
59
65
|
evaluator_name: str
|
60
|
-
score: float
|
66
|
+
score: float | bool
|
67
|
+
score_type: ScoreType
|
61
68
|
# this is marked as optional, as it is populated inside the 'measure_execution_time' decorator
|
62
69
|
evaluation_time: Optional[float] = None
|
63
70
|
input: Dict[str, Any]
|
64
71
|
expected_output: Dict[str, Any]
|
65
72
|
actual_output: Dict[str, Any]
|
66
|
-
timestamp: datetime =
|
73
|
+
timestamp: datetime = datetime.now(timezone.utc)
|
67
74
|
details: Optional[str] = None
|
68
75
|
|
69
76
|
|
@@ -76,12 +83,6 @@ class EvaluationSetResult(BaseModel):
|
|
76
83
|
average_score: float
|
77
84
|
|
78
85
|
|
79
|
-
class ScoreType(IntEnum):
|
80
|
-
BOOLEAN = 0
|
81
|
-
NUMERICAL = 1
|
82
|
-
ERROR = 2
|
83
|
-
|
84
|
-
|
85
86
|
class EvalItemResult(BaseModel):
|
86
87
|
"""Result of a single evaluation item."""
|
87
88
|
|
@@ -139,12 +139,23 @@ class ProgressReporter:
|
|
139
139
|
actual_output: dict[str, Any] = {}
|
140
140
|
for eval_result in eval_results:
|
141
141
|
# keep track of evaluator scores. this should be removed after this computation is done server-side
|
142
|
-
|
143
|
-
|
144
|
-
|
142
|
+
|
143
|
+
# check the evaluator score type
|
144
|
+
match eval_result.result.score_type:
|
145
|
+
case ScoreType.NUMERICAL:
|
146
|
+
self._evaluator_scores[eval_result.evaluator_id].append(
|
147
|
+
eval_result.result.score
|
148
|
+
)
|
149
|
+
case ScoreType.BOOLEAN:
|
150
|
+
self._evaluator_scores[eval_result.evaluator_id].append(
|
151
|
+
100 if eval_result.result.score else 0
|
152
|
+
)
|
153
|
+
case ScoreType.ERROR:
|
154
|
+
self._evaluator_scores[eval_result.evaluator_id].append(0)
|
155
|
+
|
145
156
|
evaluator_scores.append(
|
146
157
|
{
|
147
|
-
"type":
|
158
|
+
"type": eval_result.result.score_type.value,
|
148
159
|
"value": eval_result.result.score,
|
149
160
|
"justification": eval_result.result.details,
|
150
161
|
"evaluatorId": eval_result.evaluator_id,
|