feat(governance): Pydantic AI adapter#359
Open
aditik0303 wants to merge 5 commits into
Open
Conversation
Wraps agent.model with a WrapperModel deriving all four hooks from message parts (UserPromptPart -> BEFORE_MODEL, TextPart -> AFTER_MODEL, ToolCallPart -> TOOL_CALL, ToolReturnPart -> AFTER_TOOL); covers request and request_stream. Self-registers via the uipath.governance.adapters entry point; unit-tested and verified firing through the framework's real execution path. BEFORE/AFTER_AGENT remain owned by the uipath-runtime wrapper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…, framework-only can_handle) Mirror radu's LangChain-adapter review across the Pydantic AI adapter: - __init__: drop the import-time registration side-effect; registration only via the uipath.governance.adapters entry point. - can_handle: claim only a real pydantic_ai.Agent; remove the duck-typed (model/run/iter) fallback. - docstring: 'governance host' instead of uipath-runtime internals. - tests: a duck-typed look-alike is now rejected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a governance adapter for the uipath-pydantic-ai integration, enabling UiPath governance evaluators to observe and enforce policy around Pydantic AI model calls and tool usage via model-wrapping, with registration done through entry-point discovery.
Changes:
- Introduces
PydanticAIAdapter,GovernanceModel, andGovernanceCallbacksto bracket model requests/responses and tool events with governance hooks. - Adds an entry point (
uipath.governance.adapters) to register the adapter without import-time mutation of the global registry. - Adds a focused unit test suite that uses real
pydantic_aitypes and rejects duck-typed look-alikes.
Reviewed changes
Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/uipath-pydantic-ai/src/uipath_pydantic_ai/governance/adapter.py | Implements the Pydantic AI governance adapter and model wrapper that fires BEFORE_MODEL / AFTER_MODEL / TOOL_CALL / AFTER_TOOL. |
| packages/uipath-pydantic-ai/src/uipath_pydantic_ai/governance/init.py | Provides an idempotent register_governance_adapter() used by entry-point discovery (no import-time registration). |
| packages/uipath-pydantic-ai/tests/governance/test_adapter.py | Adds unit tests for can-handle behavior, attach/detach model wrapping, hook firing, and exception propagation/swallowing rules. |
| packages/uipath-pydantic-ai/tests/governance/init.py | Adds the governance tests package marker. |
| packages/uipath-pydantic-ai/pyproject.toml | Adds uipath-core dependency and a governance adapter entry point. |
| packages/uipath-pydantic-ai/uv.lock | Locks the added uipath-core dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…g path Address Copilot review on the Pydantic AI adapter: - request_stream's after-stream check caught all exceptions, swallowing GovernanceBlockException — a DENY during streaming did not abort the run, unlike the non-streaming request() path. Re-raise the block exception; keep swallowing other governance errors. Add a streaming block-propagation test. - Module docstring: registers via the uipath.governance.adapters entry point, not at import time. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These files were swept into the branch by a broad add; they are unrelated to the governance adapter. Reverting/removing them so the PR contains only governance changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
An earlier cleanup commit compared against a stale local main and wrongly removed SETUP.MD and reverted the LlamaIndex docs change. Both files come from main (PRs #352/#356), not this branch. Restore them to the main version so this PR is governance-only with no spurious deletions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Adds a Pydantic AI governance adapter to
uipath-pydantic-ai. It lets UiPath governance evaluate what a Pydantic AIAgentdoes at the model and tool level, and block disallowed actions, without the agent author writing governance code. This package contains only the Pydantic-AI-specific bridge.What it does
Detects a
pydantic_ai.Agent(can_handleclaims only realAgentinstances) and governs it by wrappingagent.modelwith aGovernanceModel(apydantic_aiWrapperModel). Both the non-streamingrequestand the streamingrequest_streampaths are bracketed.Everything flows through the model, so governance hooks are derived from the request/response messages rather than from per-event callbacks:
BEFORE_MODELAFTER_MODELToolCallPartthe model emitsTOOL_CALLToolReturnPartin the requestAFTER_TOOLOnly the latest request message is scanned each turn, so a prompt or tool result is not re-evaluated every time the full history is re-sent for context.
Enforces by letting a
GovernanceBlockException(raised on a DENY decision) propagate, stopping the model call or tool. Any other error inside a governance hook is logged and swallowed, so a governance failure cannot break an otherwise-healthy agent run.Discovered through the
uipath.governance.adaptersentry point, so no explicit import is needed to register it.What it does not do
BEFORE_AGENT/AFTER_AGENT); those are owned by the governance host.uipath-core.