uipath 2.1.36__tar.gz → 2.1.38__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.36 → uipath-2.1.38}/PKG-INFO +2 -1
- {uipath-2.1.36 → uipath-2.1.38}/pyproject.toml +2 -1
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/__init__.py +70 -31
- uipath-2.1.38/src/uipath/_cli/_dev/_terminal/_components/_chat.py +106 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_components/_details.py +31 -15
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_components/_history.py +16 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_models/_execution.py +16 -3
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_models/_messages.py +3 -2
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_styles/terminal.tcss +30 -2
- uipath-2.1.38/src/uipath/_cli/_dev/_terminal/_utils/_chat.py +240 -0
- {uipath-2.1.36/src/uipath/_cli/_dev/_terminal/_traces → uipath-2.1.38/src/uipath/_cli/_dev/_terminal/_utils}/_logger.py +3 -3
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_runtime/_contracts.py +14 -0
- uipath-2.1.38/src/uipath/_cli/cli_dev.py +66 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_init.py +3 -1
- uipath-2.1.38/src/uipath/agent/conversation/__init__.py +135 -0
- uipath-2.1.38/src/uipath/agent/conversation/async_stream.py +54 -0
- uipath-2.1.38/src/uipath/agent/conversation/citation.py +70 -0
- uipath-2.1.38/src/uipath/agent/conversation/content.py +81 -0
- uipath-2.1.38/src/uipath/agent/conversation/conversation.py +49 -0
- uipath-2.1.38/src/uipath/agent/conversation/event.py +56 -0
- uipath-2.1.38/src/uipath/agent/conversation/exchange.py +61 -0
- uipath-2.1.38/src/uipath/agent/conversation/message.py +59 -0
- uipath-2.1.38/src/uipath/agent/conversation/meta.py +11 -0
- uipath-2.1.38/src/uipath/agent/conversation/tool.py +64 -0
- {uipath-2.1.36 → uipath-2.1.38}/uv.lock +9 -1
- uipath-2.1.36/src/uipath/_cli/_dev/_terminal/_components/_resume.py +0 -35
- uipath-2.1.36/src/uipath/_cli/cli_dev.py +0 -42
- {uipath-2.1.36 → uipath-2.1.38}/.cursorrules +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.editorconfig +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.gitattributes +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/cd.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/ci.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/commitlint.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/lint.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/publish-dev.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/publish-docs.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/slack.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.github/workflows/test.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.gitignore +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.pre-commit-config.yaml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.python-version +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.vscode/extensions.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.vscode/launch.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/.vscode/settings.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/CONTRIBUTING.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/LICENSE +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/README.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/CONTRIBUTING.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/FAQ.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/assets/env-preparation-failed-dark.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/assets/env-preparation-failed-light.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/assets/favicon.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/assets/logo-dark.svg +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/assets/logo-light.svg +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/cli/index.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/actions.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets/cloud_env_var_dark.gif +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets/cloud_env_var_light.gif +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets/cloud_env_var_secret_dark.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets/cloud_env_var_secret_light.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets/copy_path_dark.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets/copy_path_light.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/assets.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/attachments.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/buckets.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/connections.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/context_grounding.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/environment_variables.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/getting_started.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/jobs.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/llm_gateway.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/processes.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/queues.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/core/traced.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/hooks.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/index.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/javascripts/extra.js +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/overrides/main.html +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/overrides/partials/actions.html +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/overrides/partials/logo.html +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/release_policy.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/sample_images/google-ADK-agent/agent-output.png +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/docs/stylesheets/extra.css +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/justfile +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/mkdocs.yml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/py.typed +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/event-trigger/.python-version +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/event-trigger/README.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/event-trigger/main.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/event-trigger/pyproject.toml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/.env.example +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/README.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/input.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/multi_tool_agent/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/multi_tool_agent/agent.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/pyproject.toml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/samples/google-ADK-agent/uv.lock +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/scripts/debug_test.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/scripts/lint_httpx_client.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/README.md +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_auth_server.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_client_credentials.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_models.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_portal_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_url_utils.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/_utils.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/auth_config.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/index.html +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/localhost.crt +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_auth/localhost.key +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_components/_json_input.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_dev/_terminal/_components/_new.py +0 -0
- {uipath-2.1.36/src/uipath/_cli/_dev/_terminal/_traces → uipath-2.1.38/src/uipath/_cli/_dev/_terminal/_utils}/_exporter.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_deterministic_evaluator_base.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_evaluator_base.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_evaluator_factory.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_exact_match_evaluator.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_json_similarity_evaluator.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_llm_as_judge_evaluator.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_evaluators/_trajectory_evaluator.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_models/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_models/_evaluation_set.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/_models/_evaluators.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/evaluation_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_evals/progress_reporter.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_push/sw_file_handler.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_runtime/_escalation.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_runtime/_hitl.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_runtime/_logging.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_runtime/_runtime.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_templates/.rels.template +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_templates/main.py.template +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_common.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_console.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_constants.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_debug.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_folders.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_input_args.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_processes.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_project_files.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_studio_project.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_tracing.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/_utils/_uv_helpers.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_auth.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_deploy.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_eval.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_invoke.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_new.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_pack.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_publish.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_pull.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_push.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/cli_run.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/middlewares.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_cli/spinner.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_config.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_execution_context.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_folder_context.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/_base_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/actions_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/api_client.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/assets_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/attachments_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/buckets_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/connections_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/context_grounding_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/folder_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/jobs_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/llm_gateway_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/processes_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_services/queues_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_uipath.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_endpoint.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_infer_bindings.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_logs.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_read_overwrites.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_request_override.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_request_spec.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_ssl_context.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_url.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/_user_agent.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/_utils/constants.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/action_schema.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/actions.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/assets.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/attachment.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/buckets.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/connections.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/context_grounding.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/context_grounding_index.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/errors.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/exceptions.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/interrupt_models.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/job.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/llm_gateway.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/processes.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/models/queues.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/py.typed +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/telemetry/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/telemetry/_constants.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/telemetry/_track.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/tracing/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/tracing/_otel_exporters.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/tracing/_traced.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/tracing/_utils.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/utils/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/src/uipath/utils/_endpoints_manager.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/__init__.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/conftest.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/evaluators/test_json_similarity_evaluator.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/mocks/bindings_script.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/mocks/pyproject.toml +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/mocks/simple_script.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/mocks/uipath-mock.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/mocks/uipath-simple-script-mock.json +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_auth.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_hitl.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_init.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_input_args.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_invoke.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_new.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_pack.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_portal_service_ensure_valid_token.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_portal_service_refresh_token.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_publish.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_pull.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_push.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_run.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/test_utils.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/utils/common.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/utils/project_details.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/cli/utils/uipath_json.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/conftest.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/conftest.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_actions_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_api_client.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_assets_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_attachments_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_base_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_buckets_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_connections_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_context_grounding_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_folder_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_jobs_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_llm_integration.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_llm_schema_cleanup.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_llm_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_processes_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_queues_service.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/test_bindings_inference.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/test_config.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/sdk/test_overwrites.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/tracing/test_otel_exporters.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/tracing/test_span_utils.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/tests/tracing/test_traced.py +0 -0
- {uipath-2.1.36 → uipath-2.1.38}/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.38
|
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
|
@@ -21,6 +21,7 @@ Requires-Dist: opentelemetry-instrumentation>=0.52b1
|
|
21
21
|
Requires-Dist: opentelemetry-sdk>=1.31.1
|
22
22
|
Requires-Dist: pathlib>=1.0.1
|
23
23
|
Requires-Dist: pydantic>=2.11.1
|
24
|
+
Requires-Dist: pyperclip>=1.9.0
|
24
25
|
Requires-Dist: python-dotenv>=1.0.1
|
25
26
|
Requires-Dist: rich>=13.0.0
|
26
27
|
Requires-Dist: tenacity>=9.0.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "uipath"
|
3
|
-
version = "2.1.
|
3
|
+
version = "2.1.38"
|
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"
|
@@ -18,6 +18,7 @@ dependencies = [
|
|
18
18
|
"azure-monitor-opentelemetry>=1.6.8",
|
19
19
|
"truststore>=0.10.1",
|
20
20
|
"textual>=5.3.0",
|
21
|
+
"pyperclip>=1.9.0",
|
21
22
|
]
|
22
23
|
classifiers = [
|
23
24
|
"Development Status :: 3 - Alpha",
|
@@ -7,10 +7,15 @@ from pathlib import Path
|
|
7
7
|
from typing import Any, Dict
|
8
8
|
from uuid import uuid4
|
9
9
|
|
10
|
+
import pyperclip # type: ignore[import-untyped]
|
11
|
+
from rich.traceback import Traceback
|
12
|
+
from textual import on
|
10
13
|
from textual.app import App, ComposeResult
|
11
14
|
from textual.binding import Binding
|
12
15
|
from textual.containers import Container, Horizontal
|
13
|
-
from textual.widgets import Button, Footer, ListView
|
16
|
+
from textual.widgets import Button, Footer, Input, ListView, RichLog
|
17
|
+
|
18
|
+
from uipath.agent.conversation import UiPathConversationEvent
|
14
19
|
|
15
20
|
from ..._runtime._contracts import (
|
16
21
|
UiPathErrorContract,
|
@@ -22,23 +27,26 @@ from ..._runtime._contracts import (
|
|
22
27
|
from ._components._details import RunDetailsPanel
|
23
28
|
from ._components._history import RunHistoryPanel
|
24
29
|
from ._components._new import NewRunPanel
|
25
|
-
from ._components._resume import ResumePanel
|
26
30
|
from ._models._execution import ExecutionRun
|
27
31
|
from ._models._messages import LogMessage, TraceMessage
|
28
|
-
from .
|
29
|
-
from .
|
32
|
+
from ._utils._chat import RunContextChatHandler, build_user_message_event
|
33
|
+
from ._utils._exporter import RunContextExporter
|
34
|
+
from ._utils._logger import RunContextLogHandler
|
30
35
|
|
31
36
|
|
32
37
|
class UiPathDevTerminal(App[Any]):
|
33
|
-
"""UiPath
|
38
|
+
"""UiPath debugging terminal interface."""
|
34
39
|
|
40
|
+
TITLE = "UiPath Debugging Terminal"
|
41
|
+
SUB_TITLE = "Interactive debugging interface for UiPath Python projects"
|
35
42
|
CSS_PATH = Path(__file__).parent / "_styles" / "terminal.tcss"
|
36
43
|
|
37
44
|
BINDINGS = [
|
38
45
|
Binding("q", "quit", "Quit"),
|
39
46
|
Binding("n", "new_run", "New"),
|
40
47
|
Binding("r", "execute_run", "Run"),
|
41
|
-
Binding("c", "
|
48
|
+
Binding("c", "copy", "Copy"),
|
49
|
+
Binding("h", "clear_history", "Clear History"),
|
42
50
|
Binding("escape", "cancel", "Cancel"),
|
43
51
|
]
|
44
52
|
|
@@ -88,8 +96,6 @@ class UiPathDevTerminal(App[Any]):
|
|
88
96
|
await self.action_execute_run()
|
89
97
|
elif event.button.id == "cancel-btn":
|
90
98
|
await self.action_cancel()
|
91
|
-
elif event.button.id == "resume-btn":
|
92
|
-
await self.action_resume()
|
93
99
|
|
94
100
|
async def on_list_view_selected(self, event: ListView.Selected) -> None:
|
95
101
|
"""Handle run selection from history."""
|
@@ -101,6 +107,31 @@ class UiPathDevTerminal(App[Any]):
|
|
101
107
|
if run:
|
102
108
|
self._show_run_details(run)
|
103
109
|
|
110
|
+
@on(Input.Submitted, "#chat-input")
|
111
|
+
async def handle_chat_input(self, event: Input.Submitted) -> None:
|
112
|
+
"""Handle user submitting text into the chat."""
|
113
|
+
user_text = event.value.strip()
|
114
|
+
if not user_text:
|
115
|
+
return
|
116
|
+
|
117
|
+
details_panel = self.query_one("#details-panel", RunDetailsPanel)
|
118
|
+
if details_panel and details_panel.current_run:
|
119
|
+
if details_panel.current_run.status != "suspended":
|
120
|
+
self.app.notify(
|
121
|
+
"Wait for agent response...", timeout=1.5, severity="warning"
|
122
|
+
)
|
123
|
+
return
|
124
|
+
self._handle_chat_event(
|
125
|
+
build_user_message_event(
|
126
|
+
user_text=user_text,
|
127
|
+
conversation_id=details_panel.current_run.id,
|
128
|
+
),
|
129
|
+
details_panel.current_run.id,
|
130
|
+
)
|
131
|
+
details_panel.current_run.resume_data = {"value": user_text}
|
132
|
+
asyncio.create_task(self._execute_runtime(details_panel.current_run))
|
133
|
+
event.input.clear()
|
134
|
+
|
104
135
|
async def action_new_run(self) -> None:
|
105
136
|
"""Show new run panel."""
|
106
137
|
new_panel = self.query_one("#new-run-panel")
|
@@ -113,20 +144,6 @@ class UiPathDevTerminal(App[Any]):
|
|
113
144
|
"""Cancel and return to new run view."""
|
114
145
|
await self.action_new_run()
|
115
146
|
|
116
|
-
async def action_resume(self) -> None:
|
117
|
-
"""Resume the suspended run."""
|
118
|
-
details_panel = self.query_one("#details-panel", RunDetailsPanel)
|
119
|
-
if details_panel and details_panel.current_run:
|
120
|
-
input: Dict[str, Any] = {}
|
121
|
-
input_data = self.query_one("#resume-panel", ResumePanel).get_input_values()
|
122
|
-
try:
|
123
|
-
input = json.loads(input_data)
|
124
|
-
except json.JSONDecodeError:
|
125
|
-
return
|
126
|
-
details_panel.current_run.resume_data = input
|
127
|
-
asyncio.create_task(self._execute_runtime(details_panel.current_run))
|
128
|
-
details_panel.switch_tab("run-tab")
|
129
|
-
|
130
147
|
async def action_execute_run(self) -> None:
|
131
148
|
"""Execute a new run with UiPath runtime."""
|
132
149
|
new_run_panel = self.query_one("#new-run-panel", NewRunPanel)
|
@@ -157,6 +174,16 @@ class UiPathDevTerminal(App[Any]):
|
|
157
174
|
history_panel.clear_runs()
|
158
175
|
await self.action_new_run()
|
159
176
|
|
177
|
+
def action_copy(self) -> None:
|
178
|
+
"""Copy content of currently focused RichLog to clipboard and notify."""
|
179
|
+
focused = self.app.focused
|
180
|
+
if isinstance(focused, RichLog):
|
181
|
+
clipboard_text = "\n".join(line.text for line in focused.lines)
|
182
|
+
pyperclip.copy(clipboard_text)
|
183
|
+
self.app.notify("Copied to clipboard!", timeout=1.5)
|
184
|
+
else:
|
185
|
+
self.app.notify("Nothing to copy here.", timeout=1.5, severity="warning")
|
186
|
+
|
160
187
|
async def _execute_runtime(self, run: ExecutionRun):
|
161
188
|
"""Execute the script using UiPath runtime."""
|
162
189
|
try:
|
@@ -166,7 +193,10 @@ class UiPathDevTerminal(App[Any]):
|
|
166
193
|
execution_id=run.id,
|
167
194
|
logs_min_level=env.get("LOG_LEVEL", "INFO"),
|
168
195
|
log_handler=RunContextLogHandler(
|
169
|
-
run_id=run.id,
|
196
|
+
run_id=run.id, callback=self._handle_log_message
|
197
|
+
),
|
198
|
+
chat_handler=RunContextChatHandler(
|
199
|
+
run_id=run.id, callback=self._handle_chat_event
|
170
200
|
),
|
171
201
|
)
|
172
202
|
|
@@ -196,17 +226,13 @@ class UiPathDevTerminal(App[Any]):
|
|
196
226
|
run.end_time = datetime.now()
|
197
227
|
|
198
228
|
except UiPathRuntimeError as e:
|
199
|
-
|
200
|
-
f"{e.error_info.code}: {e.error_info.title}\n{e.error_info.detail}"
|
201
|
-
)
|
202
|
-
self._add_error_log(run, error_msg)
|
229
|
+
self._add_error_log(run)
|
203
230
|
run.status = "failed"
|
204
231
|
run.end_time = datetime.now()
|
205
232
|
run.error = e.error_info
|
206
233
|
|
207
234
|
except Exception as e:
|
208
|
-
|
209
|
-
self._add_error_log(run, error_msg)
|
235
|
+
self._add_error_log(run)
|
210
236
|
run.status = "failed"
|
211
237
|
run.end_time = datetime.now()
|
212
238
|
run.error = UiPathErrorContract(
|
@@ -262,14 +288,27 @@ class UiPathDevTerminal(App[Any]):
|
|
262
288
|
details_panel = self.query_one("#details-panel", RunDetailsPanel)
|
263
289
|
details_panel.add_log(log_msg)
|
264
290
|
|
291
|
+
def _handle_chat_event(
|
292
|
+
self, event: UiPathConversationEvent, execution_id: str
|
293
|
+
) -> None:
|
294
|
+
updated_chat_message = self.runs[execution_id].add_message(event)
|
295
|
+
if not updated_chat_message:
|
296
|
+
return
|
297
|
+
details_panel = self.app.query_one("#details-panel", RunDetailsPanel)
|
298
|
+
details_panel.add_chat_message(event, updated_chat_message, execution_id)
|
299
|
+
|
265
300
|
def _add_info_log(self, run: ExecutionRun, message: str):
|
266
301
|
"""Add info log to run."""
|
267
302
|
timestamp = datetime.now()
|
268
303
|
log_msg = LogMessage(run.id, "INFO", message, timestamp)
|
269
304
|
self._handle_log_message(log_msg)
|
270
305
|
|
271
|
-
def _add_error_log(self, run: ExecutionRun
|
306
|
+
def _add_error_log(self, run: ExecutionRun):
|
272
307
|
"""Add error log to run."""
|
273
308
|
timestamp = datetime.now()
|
274
|
-
|
309
|
+
tb = Traceback(
|
310
|
+
show_locals=False,
|
311
|
+
max_frames=4,
|
312
|
+
)
|
313
|
+
log_msg = LogMessage(run.id, "ERROR", tb, timestamp)
|
275
314
|
self._handle_log_message(log_msg)
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import time
|
2
|
+
from typing import Dict, List, Union
|
3
|
+
|
4
|
+
from textual.app import ComposeResult
|
5
|
+
from textual.containers import Container, Vertical, VerticalScroll
|
6
|
+
from textual.widgets import Input, Markdown
|
7
|
+
|
8
|
+
from uipath.agent.conversation import (
|
9
|
+
UiPathConversationEvent,
|
10
|
+
UiPathConversationMessage,
|
11
|
+
UiPathExternalValue,
|
12
|
+
UiPathInlineValue,
|
13
|
+
)
|
14
|
+
|
15
|
+
|
16
|
+
class Prompt(Markdown):
|
17
|
+
pass
|
18
|
+
|
19
|
+
|
20
|
+
class Response(Markdown):
|
21
|
+
BORDER_TITLE = "🤖 ai"
|
22
|
+
|
23
|
+
|
24
|
+
class Tool(Markdown):
|
25
|
+
BORDER_TITLE = "🛠️ tool"
|
26
|
+
|
27
|
+
|
28
|
+
class ChatPanel(Container):
|
29
|
+
"""Panel for displaying and interacting with chat messages."""
|
30
|
+
|
31
|
+
_chat_widgets: Dict[str, Markdown]
|
32
|
+
_last_update_time: Dict[str, float]
|
33
|
+
|
34
|
+
def __init__(self, **kwargs):
|
35
|
+
super().__init__(**kwargs)
|
36
|
+
self._chat_widgets = {}
|
37
|
+
self._last_update_time = {}
|
38
|
+
|
39
|
+
def compose(self) -> ComposeResult:
|
40
|
+
with Vertical(id="chat-container"):
|
41
|
+
yield VerticalScroll(id="chat-view")
|
42
|
+
yield Input(
|
43
|
+
placeholder="Type your message and press Enter...",
|
44
|
+
id="chat-input",
|
45
|
+
)
|
46
|
+
|
47
|
+
def add_chat_message(
|
48
|
+
self, event: UiPathConversationEvent, chat_msg: UiPathConversationMessage
|
49
|
+
) -> None:
|
50
|
+
"""Add or update a chat message bubble."""
|
51
|
+
chat_view = self.query_one("#chat-view")
|
52
|
+
|
53
|
+
widget_cls: Union[type[Prompt], type[Response], type[Tool]]
|
54
|
+
if chat_msg.role == "user":
|
55
|
+
widget_cls = Prompt
|
56
|
+
elif chat_msg.role == "assistant":
|
57
|
+
widget_cls = Response
|
58
|
+
else:
|
59
|
+
widget_cls = Response
|
60
|
+
|
61
|
+
parts: List[str] = []
|
62
|
+
if chat_msg.content_parts:
|
63
|
+
for part in chat_msg.content_parts:
|
64
|
+
if (
|
65
|
+
part.mime_type.startswith("text/")
|
66
|
+
or part.mime_type == "application/json"
|
67
|
+
):
|
68
|
+
if isinstance(part.data, UiPathInlineValue):
|
69
|
+
parts.append(part.data.inline or "")
|
70
|
+
elif isinstance(part.data, UiPathExternalValue):
|
71
|
+
parts.append(f"[external: {part.data.url}]")
|
72
|
+
|
73
|
+
text_block = "\n".join(parts).strip()
|
74
|
+
content_lines = [f"{text_block}"] if text_block else []
|
75
|
+
|
76
|
+
if chat_msg.tool_calls:
|
77
|
+
widget_cls = Tool
|
78
|
+
for call in chat_msg.tool_calls:
|
79
|
+
status_icon = "✓" if call.result else "⚙"
|
80
|
+
content_lines.append(f" {status_icon} **{call.name}**")
|
81
|
+
|
82
|
+
if not content_lines:
|
83
|
+
return
|
84
|
+
|
85
|
+
content = "\n\n".join(content_lines)
|
86
|
+
|
87
|
+
existing = self._chat_widgets.get(chat_msg.message_id)
|
88
|
+
now = time.monotonic()
|
89
|
+
last_update = self._last_update_time.get(chat_msg.message_id, 0.0)
|
90
|
+
|
91
|
+
if existing:
|
92
|
+
should_update = (
|
93
|
+
event.exchange
|
94
|
+
and event.exchange.message
|
95
|
+
and event.exchange.message.end is not None
|
96
|
+
)
|
97
|
+
if should_update or now - last_update > 0.15:
|
98
|
+
existing.update(content)
|
99
|
+
self._last_update_time[chat_msg.message_id] = now
|
100
|
+
chat_view.scroll_end(animate=False)
|
101
|
+
else:
|
102
|
+
widget_instance = widget_cls(content)
|
103
|
+
chat_view.mount(widget_instance)
|
104
|
+
self._chat_widgets[chat_msg.message_id] = widget_instance
|
105
|
+
self._last_update_time[chat_msg.message_id] = now
|
106
|
+
chat_view.scroll_end(animate=False)
|
@@ -3,12 +3,14 @@ from typing import Dict, List, Optional
|
|
3
3
|
from textual.app import ComposeResult
|
4
4
|
from textual.containers import Container, Horizontal, Vertical
|
5
5
|
from textual.reactive import reactive
|
6
|
-
from textual.widgets import RichLog, TabbedContent, TabPane, Tree
|
6
|
+
from textual.widgets import Input, RichLog, TabbedContent, TabPane, Tree
|
7
7
|
from textual.widgets.tree import TreeNode
|
8
8
|
|
9
|
+
from uipath.agent.conversation import UiPathConversationEvent, UiPathConversationMessage
|
10
|
+
|
9
11
|
from .._models._execution import ExecutionRun
|
10
12
|
from .._models._messages import LogMessage, TraceMessage
|
11
|
-
from .
|
13
|
+
from ._chat import ChatPanel
|
12
14
|
|
13
15
|
|
14
16
|
class SpanDetailsDisplay(Container):
|
@@ -116,8 +118,8 @@ class RunDetailsPanel(Container):
|
|
116
118
|
classes="detail-log",
|
117
119
|
)
|
118
120
|
|
119
|
-
with TabPane("
|
120
|
-
yield
|
121
|
+
with TabPane("Chat", id="chat-tab"):
|
122
|
+
yield ChatPanel(id="chat-panel")
|
121
123
|
|
122
124
|
def watch_current_run(
|
123
125
|
self, old_value: Optional[ExecutionRun], new_value: Optional[ExecutionRun]
|
@@ -151,9 +153,9 @@ class RunDetailsPanel(Container):
|
|
151
153
|
tabbed = self.query_one(TabbedContent)
|
152
154
|
tabbed.active = tab_id
|
153
155
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
156
|
+
def _update_chat_tab(self, run: ExecutionRun) -> None:
|
157
|
+
chat_input = self.query_one("#chat-input", Input)
|
158
|
+
chat_input.disabled = run.status == "completed" or run.status == "failed"
|
157
159
|
|
158
160
|
def _flatten_values(self, value: object, prefix: str = "") -> list[str]:
|
159
161
|
"""Flatten nested dict/list structures into dot-notation paths."""
|
@@ -210,7 +212,7 @@ class RunDetailsPanel(Container):
|
|
210
212
|
|
211
213
|
def _show_run_details(self, run: ExecutionRun):
|
212
214
|
"""Display detailed information about the run in the Details tab."""
|
213
|
-
self.
|
215
|
+
self._update_chat_tab(run)
|
214
216
|
|
215
217
|
run_details_log = self.query_one("#run-details-log", RichLog)
|
216
218
|
run_details_log.clear()
|
@@ -416,14 +418,28 @@ class RunDetailsPanel(Container):
|
|
416
418
|
timestamp_str = log_msg.timestamp.strftime("%H:%M:%S")
|
417
419
|
level_short = log_msg.level[:4].upper()
|
418
420
|
|
419
|
-
log_text = (
|
420
|
-
f"[dim]{timestamp_str}[/dim] "
|
421
|
-
f"[{color}]{level_short}[/{color}] "
|
422
|
-
f"{log_msg.message}"
|
423
|
-
)
|
424
|
-
|
425
421
|
logs_log = self.query_one("#logs-log", RichLog)
|
426
|
-
|
422
|
+
if isinstance(log_msg.message, str):
|
423
|
+
log_text = (
|
424
|
+
f"[dim]{timestamp_str}[/dim] "
|
425
|
+
f"[{color}]{level_short}[/{color}] "
|
426
|
+
f"{log_msg.message}"
|
427
|
+
)
|
428
|
+
logs_log.write(log_text)
|
429
|
+
else:
|
430
|
+
logs_log.write(log_msg.message)
|
431
|
+
|
432
|
+
def add_chat_message(
|
433
|
+
self,
|
434
|
+
event: UiPathConversationEvent,
|
435
|
+
chat_msg: UiPathConversationMessage,
|
436
|
+
run_id: str,
|
437
|
+
) -> None:
|
438
|
+
"""Add a chat message to the display."""
|
439
|
+
if not self.current_run or run_id != self.current_run.id:
|
440
|
+
return
|
441
|
+
chat_panel = self.query_one("#chat-panel", ChatPanel)
|
442
|
+
chat_panel.add_chat_message(event, chat_msg)
|
427
443
|
|
428
444
|
def clear_display(self):
|
429
445
|
"""Clear both traces and logs display."""
|
@@ -34,6 +34,10 @@ class RunHistoryPanel(Container):
|
|
34
34
|
classes="new-run-btn",
|
35
35
|
)
|
36
36
|
|
37
|
+
def on_mount(self) -> None:
|
38
|
+
# Update only running items every 5 seconds
|
39
|
+
self.set_interval(5.0, self._refresh_running_items)
|
40
|
+
|
37
41
|
def add_run(self, run: ExecutionRun):
|
38
42
|
"""Add a new run to history."""
|
39
43
|
self.runs.insert(0, run) # Add to top
|
@@ -67,3 +71,15 @@ class RunHistoryPanel(Container):
|
|
67
71
|
"""Clear all runs from history."""
|
68
72
|
self.runs.clear()
|
69
73
|
self.refresh_list()
|
74
|
+
|
75
|
+
def _refresh_running_items(self) -> None:
|
76
|
+
if not any(run.status == "running" for run in self.runs):
|
77
|
+
return None # No running items, skip update
|
78
|
+
|
79
|
+
run_list = self.query_one("#run-list", ListView)
|
80
|
+
|
81
|
+
for item in run_list.children:
|
82
|
+
run = self.get_run_by_id(item.run_id) # type: ignore[attr-defined]
|
83
|
+
if run and run.status == "running":
|
84
|
+
static = item.query_one(Static)
|
85
|
+
static.update(run.display_name)
|
@@ -5,7 +5,10 @@ from uuid import uuid4
|
|
5
5
|
|
6
6
|
from rich.text import Text
|
7
7
|
|
8
|
+
from uipath.agent.conversation import UiPathConversationEvent, UiPathConversationMessage
|
9
|
+
|
8
10
|
from ...._runtime._contracts import UiPathErrorContract
|
11
|
+
from .._utils._chat import ConversationAggregator
|
9
12
|
from ._messages import LogMessage, TraceMessage
|
10
13
|
|
11
14
|
|
@@ -20,10 +23,11 @@ class ExecutionRun:
|
|
20
23
|
self.output_data: Optional[Dict[str, Any]] = None
|
21
24
|
self.start_time = datetime.now()
|
22
25
|
self.end_time: Optional[datetime] = None
|
23
|
-
self.status = "running" # running, completed, failed
|
26
|
+
self.status = "running" # running, completed, failed, suspended
|
24
27
|
self.traces: List[TraceMessage] = []
|
25
28
|
self.logs: List[LogMessage] = []
|
26
29
|
self.error: Optional[UiPathErrorContract] = None
|
30
|
+
self.chat_aggregator = ConversationAggregator()
|
27
31
|
|
28
32
|
@property
|
29
33
|
def duration(self) -> str:
|
@@ -53,14 +57,23 @@ class ExecutionRun:
|
|
53
57
|
script_name = (
|
54
58
|
os.path.basename(self.entrypoint) if self.entrypoint else "untitled"
|
55
59
|
)
|
56
|
-
truncated_script = script_name[:
|
60
|
+
truncated_script = script_name[:8]
|
57
61
|
time_str = self.start_time.strftime("%H:%M:%S")
|
58
62
|
duration_str = self.duration[:6]
|
59
63
|
|
60
64
|
text = Text()
|
61
65
|
text.append(f"{status_icon:<2} ", style=status_colors.get(self.status, "white"))
|
62
|
-
text.append(f"{truncated_script:<
|
66
|
+
text.append(f"{truncated_script:<8} ")
|
63
67
|
text.append(f"({time_str:<8}) ")
|
64
68
|
text.append(f"[{duration_str:<6}]")
|
65
69
|
|
66
70
|
return text
|
71
|
+
|
72
|
+
@property
|
73
|
+
def messages(self) -> List[UiPathConversationMessage]:
|
74
|
+
return list(self.chat_aggregator.messages.values())
|
75
|
+
|
76
|
+
def add_message(
|
77
|
+
self, event: UiPathConversationEvent
|
78
|
+
) -> Optional[UiPathConversationMessage]:
|
79
|
+
return self.chat_aggregator.add_event(event)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Any, Dict, Optional
|
2
|
+
from typing import Any, Dict, Optional, Union
|
3
3
|
|
4
|
+
from rich.console import RenderableType
|
4
5
|
from textual.message import Message
|
5
6
|
|
6
7
|
|
@@ -28,7 +29,7 @@ class LogMessage(Message):
|
|
28
29
|
self,
|
29
30
|
run_id: str,
|
30
31
|
level: str,
|
31
|
-
message: str,
|
32
|
+
message: Union[str, RenderableType],
|
32
33
|
timestamp: Optional[datetime] = None,
|
33
34
|
):
|
34
35
|
self.run_id = run_id
|
@@ -64,7 +64,8 @@ Screen {
|
|
64
64
|
}
|
65
65
|
|
66
66
|
.run-actions {
|
67
|
-
|
67
|
+
dock: bottom;
|
68
|
+
height: auto;
|
68
69
|
align: left middle;
|
69
70
|
}
|
70
71
|
|
@@ -204,7 +205,7 @@ SpanDetailsDisplay {
|
|
204
205
|
|
205
206
|
.json-input {
|
206
207
|
margin-top: 1;
|
207
|
-
height:
|
208
|
+
height: auto;
|
208
209
|
}
|
209
210
|
|
210
211
|
.run-actions {
|
@@ -222,3 +223,30 @@ SpanDetailsDisplay {
|
|
222
223
|
TextArea.invalid {
|
223
224
|
border: tall red;
|
224
225
|
}
|
226
|
+
|
227
|
+
|
228
|
+
Prompt {
|
229
|
+
border: wide $primary-background;
|
230
|
+
background: $surface;
|
231
|
+
color: $text;
|
232
|
+
margin-right: 8;
|
233
|
+
margin-left: 1;
|
234
|
+
padding: 1 1 0 1;
|
235
|
+
}
|
236
|
+
Response, Tool {
|
237
|
+
border: wide $primary-background;
|
238
|
+
background: $surface;
|
239
|
+
color: $text;
|
240
|
+
margin: 1;
|
241
|
+
margin-left: 8;
|
242
|
+
padding: 1 1 0 1;
|
243
|
+
}
|
244
|
+
|
245
|
+
#chat-container{
|
246
|
+
background: $surface;
|
247
|
+
}
|
248
|
+
|
249
|
+
#chat-input{
|
250
|
+
dock: bottom;
|
251
|
+
margin: 1;
|
252
|
+
}
|