Skip to content

refactor(core): drop AdapterRegistry + BaseAdapter; keep EvaluatorProtocol#1761

Open
viswa-uipath wants to merge 1 commit into
mainfrom
feat/adapter-fix
Open

refactor(core): drop AdapterRegistry + BaseAdapter; keep EvaluatorProtocol#1761
viswa-uipath wants to merge 1 commit into
mainfrom
feat/adapter-fix

Conversation

@viswa-uipath

@viswa-uipath viswa-uipath commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Delete the AdapterRegistry / BaseAdapter / GovernedAgentBase plumbing from uipath-core, plus the uipath.governance.adapters entry-point group and get_adapter_registry / reset_adapter_registry helpers
  • Keep EvaluatorProtocol — the one contract framework plugins still consume
  • Bump uipath-core to 0.5.23 and refresh the three uv.lock files

Why

The adapter registry was a second plugin-discovery system keyed on the same fact (which framework is active) that UiPathRuntimeFactoryRegistry already resolves statically. It existed to support an open-PR pattern where the runtime layer would sniff the framework off an opaque agent — that approach is being abandoned in favor of framework plugins wiring governance at their own native seam (callback handlers / hook lists), so the registry becomes dead weight.

The only known external consumer is the unmerged uipath-langchain PR #899, which is being reshaped to consume EvaluatorProtocol directly through its factory. A grep across the monorepo (.py / .toml / .md / .rst / .json) for AdapterRegistry / BaseAdapter / GovernedAgentBase / get_adapter_registry / reset_adapter_registry returns zero hits outside the deleted files.

Changes

Action Path
Delete packages/uipath-core/src/uipath/core/adapters/base.py
Delete packages/uipath-core/src/uipath/core/adapters/registry.py
Delete packages/uipath-core/tests/adapters/test_base.py
Delete packages/uipath-core/tests/adapters/test_registry.py
Update packages/uipath-core/src/uipath/core/adapters/__init__.py — exports trimmed to EvaluatorProtocol
Update packages/uipath-core/pyproject.toml0.5.22 → 0.5.23
Update three uv.lock files for the workspace

Net diff: −962 LOC.

Test plan

  • uv run ruff check src/ tests/ — clean
  • uv run mypy src/ — clean (45 source files)
  • uv run pytest230 passed, 1 skipped in uipath-core
  • Monorepo grep confirms no remaining references to deleted symbols
  • CI on PR for uipath / uipath-platform packages
  • Coordinate with uipath-langchain PR chore: validate required files on push #899 reshape (see below)

Coordination

Downstream uipath-runtime-python and uipath-langchain-python are not yet merged, so no shipped consumer breaks. Merge order if this lands first:

  1. This PR (uipath-core deletion + version bump) — ready now
  2. uipath-runtime-python adds optional evaluator kwarg to the factory protocol — pending
  3. uipath-langchain-python PR chore: validate required files on push #899 reshaped to factory-driven GovernanceCallbackHandler wiring (and to subclass langchain_core.callbacks.BaseCallbackHandler properly) — pending

🤖 Generated with Claude Code

Development Packages

uipath

[project]
dependencies = [
  # Exact version (copy-paste ready):
  "uipath==2.11.13.dev1017616976",

  # Any version from this PR (uncomment to use a range instead):
  # "uipath>=2.11.13.dev1017610000,<2.11.13.dev1017620000",
]

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true

[tool.uv.sources]
uipath = { index = "testpypi" }
uipath-platform = { index = "testpypi" }
uipath-core = { index = "testpypi" }

[tool.uv]
override-dependencies = ["uipath-platform==0.1.79.dev1017616976", "uipath-core==0.5.24.dev1017616976"]

uipath-core

[project]
dependencies = [
  # Exact version (copy-paste ready):
  "uipath-core==0.5.24.dev1017616976",

  # Any version from this PR (uncomment to use a range instead):
  # "uipath-core>=0.5.24.dev1017610000,<0.5.24.dev1017620000",
]

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true

[tool.uv.sources]
uipath-core = { index = "testpypi" }

uipath-platform

[project]
dependencies = [
  # Exact version (copy-paste ready):
  "uipath-platform==0.1.78.dev1017616971",

  # Any version from this PR (uncomment to use a range instead):
  # "uipath-platform>=0.1.78.dev1017610000,<0.1.78.dev1017620000",
]

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true

[tool.uv.sources]
uipath-platform = { index = "testpypi" }
uipath-core = { index = "testpypi" }

[tool.uv]
override-dependencies = ["uipath-core==0.5.23.dev1017616971"]

Copilot AI review requested due to automatic review settings June 25, 2026 03:09
@github-actions github-actions Bot added test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-runtime test:uipath-integrations labels Jun 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the adapter-registry plumbing from uipath-core (adapter base class, registry singleton, and related tests) while preserving EvaluatorProtocol as the remaining contract for framework governance integrations. It also bumps uipath-core’s version and refreshes workspace lockfiles to reflect the new core version and updated uv lock metadata.

Changes:

  • Deleted BaseAdapter / AdapterRegistry / singleton helpers (and their tests), leaving only EvaluatorProtocol under uipath.core.adapters.
  • Updated uipath.core.adapters public exports/documentation accordingly.
  • Bumped uipath-core to 0.5.23 and refreshed uv.lock files across packages.

Reviewed changes

Copilot reviewed 6 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/uipath/uv.lock Refresh lock metadata and update editable uipath-core version reference to 0.5.23.
packages/uipath-platform/uv.lock Refresh lock metadata and update editable uipath-core version reference to 0.5.23.
packages/uipath-core/uv.lock Update uipath-core package version entry to 0.5.23 in the lock.
packages/uipath-core/tests/adapters/test_registry.py Remove tests for deleted adapter registry behavior.
packages/uipath-core/tests/adapters/test_base.py Remove tests for deleted adapter base/proxy behavior.
packages/uipath-core/src/uipath/core/adapters/registry.py Delete adapter registry + entry-point discovery implementation.
packages/uipath-core/src/uipath/core/adapters/base.py Delete adapter base class and governed proxy base.
packages/uipath-core/src/uipath/core/adapters/init.py Trim exports to only EvaluatorProtocol and update docstring.
packages/uipath-core/pyproject.toml Bump package version from 0.5.22 to 0.5.23.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/uipath-core/pyproject.toml Outdated
@viswa-uipath viswa-uipath added the build:dev Create a dev build from the pr label Jun 25, 2026
viswa-uipath added a commit that referenced this pull request Jun 25, 2026
Unblocks architecture-review §2.4 on the uipath-runtime side. The
prescription there is to hoist the policy fetch from the runtime-layer
``PolicyLoader`` (which today spins a daemon thread inside an async
runtime and blocks on ``threading.Event.wait(timeout=10s)``) up to the
async host: the CLI calls ``await provider.get_policy_async(ctx)``
itself, builds the ``PolicyIndex``, and passes the resolved index +
mode into ``GovernanceRuntime``. The runtime collapses to a pure,
synchronous-to-construct decorator — no thread, no Event, no
``is_conversational`` in the ctor.

For that to type-check on the runtime side, the structural
``GovernancePolicyProvider`` Protocol in uipath-core needs to declare
``get_policy_async``. The concrete platform provider
(``UiPathPlatformGovernanceProvider``) already implements it; the
contract was just lying about what providers expose.

Changes
- ``GovernancePolicyProvider`` now declares both ``get_policy`` and
  ``async get_policy_async``. Both required (the platform impl ships
  both today, and the doc's recommended caller path is the async
  variant — sync stays for non-event-loop callers like integration
  tests and CLI tools).
- ``_FakePolicyProvider`` in the conformance tests grew the async
  method and a separate ``async_calls`` recorder.
- New ``test_policy_round_trip_async`` exercises the async path via
  ``@pytest.mark.asyncio`` and pins that the two entry points are
  independent (calling one doesn't touch the other's recorder).

Verified
- uipath-core: ruff clean, mypy clean (45 source files), 32
  governance tests passed.
- uipath-platform: protocol-conformance tests still pass
  (9 passed) — ``UiPathPlatformGovernanceProvider`` already exposed
  ``get_policy_async``, so the now-stricter protocol still accepts it
  structurally.

No version bump — rides on the unreleased 0.5.23 that already carries
PR #1761's §1.1 (adapter-registry deletion) and §1.2 (typed
EvaluatorProtocol returns).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚨 Heads up: uipath-langchain cross-tests are FAILING 🚨

Your changes may break the uipath-langchain-python integration.

⚠️ These checks are NOT enforced by branch protection rules. Please review the failures before merging.

🔍 Inspect the failed run →

viswa-uipath added a commit that referenced this pull request Jun 27, 2026
Unblocks architecture-review §2.4 on the uipath-runtime side. The
prescription there is to hoist the policy fetch from the runtime-layer
``PolicyLoader`` (which today spins a daemon thread inside an async
runtime and blocks on ``threading.Event.wait(timeout=10s)``) up to the
async host: the CLI calls ``await provider.get_policy_async(ctx)``
itself, builds the ``PolicyIndex``, and passes the resolved index +
mode into ``GovernanceRuntime``. The runtime collapses to a pure,
synchronous-to-construct decorator — no thread, no Event, no
``is_conversational`` in the ctor.

For that to type-check on the runtime side, the structural
``GovernancePolicyProvider`` Protocol in uipath-core needs to declare
``get_policy_async``. The concrete platform provider
(``UiPathPlatformGovernanceProvider``) already implements it; the
contract was just lying about what providers expose.

Changes
- ``GovernancePolicyProvider`` now declares both ``get_policy`` and
  ``async get_policy_async``. Both required (the platform impl ships
  both today, and the doc's recommended caller path is the async
  variant — sync stays for non-event-loop callers like integration
  tests and CLI tools).
- ``_FakePolicyProvider`` in the conformance tests grew the async
  method and a separate ``async_calls`` recorder.
- New ``test_policy_round_trip_async`` exercises the async path via
  ``@pytest.mark.asyncio`` and pins that the two entry points are
  independent (calling one doesn't touch the other's recorder).

Verified
- uipath-core: ruff clean, mypy clean (45 source files), 32
  governance tests passed.
- uipath-platform: protocol-conformance tests still pass
  (9 passed) — ``UiPathPlatformGovernanceProvider`` already exposed
  ``get_policy_async``, so the now-stricter protocol still accepts it
  structurally.

No version bump — rides on the unreleased 0.5.23 that already carries
PR #1761's §1.1 (adapter-registry deletion) and §1.2 (typed
EvaluatorProtocol returns).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@viswa-uipath viswa-uipath removed the build:dev Create a dev build from the pr label Jun 27, 2026
…tocol

Delete the AdapterRegistry / BaseAdapter / GovernedAgentBase plumbing
from uipath-core plus the uipath.governance.adapters entry-point group
and the get_adapter_registry / reset_adapter_registry helpers. Keep
EvaluatorProtocol — the one contract framework plugins still consume.

The adapter registry was a second plugin-discovery system keyed on the
same fact (which framework is active) that UiPathRuntimeFactoryRegistry
already resolves statically. It existed to support an open-PR pattern
where the runtime layer would sniff the framework off an opaque agent;
that approach is being abandoned in favor of framework plugins wiring
governance at their own native seam, so the registry becomes dead
weight. Grep across the monorepo confirms zero remaining consumers
outside the deleted files.

Companion changes landing in the same PR
----------------------------------------

- EvaluatorProtocol returns are typed as AuditRecord (was an untyped
  list); the trace_id field is dropped from AuditRecord and the
  protocol since per-evaluation trace ids aren't part of the contract.
- GovernancePolicyProvider grows get_policy_async so async hosts can
  fetch the policy pack without thread-pool offloading.
- GovernanceService self-resolves the compensation trace_id when the
  caller leaves it empty (same fallback chain track_event uses). Lets
  the runtime layer stay env-free; new tests cover both fill and
  no-source branches.

Version bumps and pins
----------------------

- uipath-core 0.5.22 → 0.5.24
- uipath-platform 0.1.7x → 0.1.79; pin raised to uipath-core>=0.5.24
- uipath is unchanged (no source-level edits in this PR); its uv.lock
  refreshes only to pick up the bumped uipath-core / uipath-platform
  versions

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@viswa-uipath viswa-uipath added the build:dev Create a dev build from the pr label Jun 27, 2026
viswa-uipath added a commit to UiPath/uipath-runtime-python that referenced this pull request Jun 27, 2026
Rebase of the guardrail-compensation series onto feat/governance-audit's
tip. Brings up the native governance layer in one squash:

  - In-runtime policy evaluator (native/evaluator.py): rule + check +
    condition matching with VADER sentiment / chardet / regex / entropy
    / incident / commitment operators. Honors per-check action overrides
    and cross-rule aggregation. Instance-scoped with explicit deps
    (AuditManager + GuardrailCompensator) injected by the host.
  - Native package exports (native/__init__.py): build_policy_index_from_yaml
    + GovernanceEvaluator + GuardrailCompensator + CheckContext + PolicyIndex.
  - GuardrailCompensator (native/guardrail_compensation.py): bounded
    ThreadPoolExecutor + BoundedSemaphore per runtime, contextvars
    propagation, weakref-tracked process-level atexit. Delegates HTTP /
    auth / URL / trace correlation to the injected
    GovernanceCompensationProvider.
  - Drop PolicyLoader: host fetches policy asynchronously via
    GovernancePolicyProvider and hands the resolved PolicyIndex to
    UiPathGovernedRuntime at construction.
  - Trace correlation: AuditEvent / AuditRecord no longer carry trace_id;
    OTel-backed sinks resolve from the live span via the
    AuditManager's captured contextvars snapshot.
  - testpypi dev pin (pyproject.toml): uipath-core
    0.5.24.dev1017610000..0.5.24.dev1017620000 from PR
    UiPath/uipath-python#1761 (AdapterRegistry deletion +
    AuditRecord.trace_id field drop).

Tests: 346 passed + 1 skipped, ruff + mypy clean.

Pre-rebase tip preserved at backup-guardrail-pre-audit-rebase-2026-06-28
for reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
viswa-uipath added a commit to UiPath/uipath-runtime-python that referenced this pull request Jun 28, 2026
Rebase of the guardrail-compensation series onto feat/governance-audit's
tip. Brings up the native governance layer in one squash:

  - In-runtime policy evaluator (native/evaluator.py): rule + check +
    condition matching with VADER sentiment / chardet / regex / entropy
    / incident / commitment operators. Honors per-check action overrides
    and cross-rule aggregation. Instance-scoped with explicit deps
    (AuditManager + GuardrailCompensator) injected by the host.
  - Native package exports (native/__init__.py): build_policy_index_from_yaml
    + GovernanceEvaluator + GuardrailCompensator + CheckContext + PolicyIndex.
  - GuardrailCompensator (native/guardrail_compensation.py): bounded
    ThreadPoolExecutor + BoundedSemaphore per runtime, contextvars
    propagation, weakref-tracked process-level atexit. Delegates HTTP /
    auth / URL / trace correlation to the injected
    GovernanceCompensationProvider.
  - Drop PolicyLoader: host fetches policy asynchronously via
    GovernancePolicyProvider and hands the resolved PolicyIndex to
    UiPathGovernedRuntime at construction.
  - Trace correlation: AuditEvent / AuditRecord no longer carry trace_id;
    OTel-backed sinks resolve from the live span via the
    AuditManager's captured contextvars snapshot.
  - testpypi dev pin (local dev only): uipath-core + uipath-platform
    pinned to the testpypi dev builds from PR
    UiPath/uipath-python#1761 (AdapterRegistry deletion +
    AuditRecord.trace_id field drop) via ``[tool.uv]
    override-dependencies`` + ``[tool.uv.sources]``. The wheel-baked
    ``[project.dependencies]`` constraint stays at the canonical
    ``uipath-core>=0.5.22,<0.6.0`` so consumer workspaces that don't
    configure testpypi (notably uipath-python's CI matrix) resolve
    cleanly against published versions.

Tests: 346 passed + 1 skipped, ruff + mypy clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build:dev Create a dev build from the pr test:uipath-integrations test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants