feat(governance): MS Agent Framework adapter#361
Open
aditik0303 wants to merge 9 commits into
Open
Conversation
Appends a ChatMiddleware (BEFORE/AFTER_MODEL) and FunctionMiddleware (TOOL_CALL/AFTER_TOOL) to agent.middleware; walks WorkflowAgent executors for multi-agent apps. 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 MS Agent Framework adapter: - __init__: drop the import-time registration side-effect; registration only via the uipath.governance.adapters entry point. - can_handle: claim only a real agent_framework.BaseAgent; remove the duck-typed (middleware + run/workflow) fallback. - docstring: 'governance host' instead of uipath-runtime internals. - tests: can_handle uses a real BaseAgent; duck-typed look-alikes are now rejected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a Microsoft Agent Framework governance adapter to uipath-agent-framework, wired via entry-point discovery, and aligns runtime/model plumbing with upstream client API changes.
Changes:
- Introduces an Agent Framework governance adapter + middleware that fires BEFORE_MODEL/AFTER_MODEL and TOOL_CALL/AFTER_TOOL hooks.
- Adds a governance adapter entry point and new
uipath-coredependency, plus corresponding lockfile updates. - Updates chat client construction and runtime schema model-name extraction to prefer
model(withmodel_idfallback).
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/uipath-agent-framework/uv.lock | Locks in the new uipath-core dependency for the package. |
| packages/uipath-agent-framework/pyproject.toml | Adds uipath-core dependency and a uipath.governance.adapters entry point for governance adapter discovery. |
| packages/uipath-agent-framework/src/uipath_agent_framework/governance/adapter.py | New governance adapter + middleware implementation for Agent Framework agents and workflows. |
| packages/uipath-agent-framework/src/uipath_agent_framework/governance/init.py | Provides register_governance_adapter() and avoids import-time registration; exposes public symbols. |
| packages/uipath-agent-framework/tests/governance/test_adapter.py | New unit tests covering can_handle, attach/detach, hook bracketing, blocking behavior, and exception swallowing. |
| packages/uipath-agent-framework/tests/governance/init.py | Adds governance test package marker. |
| packages/uipath-agent-framework/src/uipath_agent_framework/runtime/schema.py | Updates model-name extraction to support client.model with model_id fallback. |
| packages/uipath-agent-framework/src/uipath_agent_framework/chat/openai.py | Updates OpenAI client initialization to pass model= instead of model_id=. |
| packages/uipath-agent-framework/src/uipath_agent_framework/chat/anthropic.py | Updates Anthropic client initialization to pass model= instead of model_id=. |
| packages/uipath-agent-framework/src/uipath_agent_framework/_cli/_templates/main.py.template | Updates template usage to OpenAIChatClient(model=...). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…apter Module docstring: registers via the uipath.governance.adapters entry point, not at import time. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The model/model_id chat-client tweak in runtime/schema.py is unrelated to the governance adapter and was bundled in accidentally. Revert it to main so this PR is governance-only. 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>
Record that payload text is read via `.text` rather than isinstance on agent-framework message/response models, since those shapes are still pre-release (rc) and not stable public types. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…valuator Core PR #1761 removed BaseAdapter from uipath-core. Migrate to the factory-evaluator pattern (matching #899): - governance/adapter.py -> middleware.py: replace the BaseAdapter subclass (name/can_handle/attach/detach) with module-level install_governance() that appends the governance middleware to each agent's middleware list (walking WorkflowAgent executors); keep the middleware classes + callbacks. File named for its seam (middleware). - runtime/factory.py: new_runtime reads `evaluator` from kwargs and calls install_governance. - governance/__init__.py: drop register_governance_adapter + registry import; expose install_governance. No import-time side effects. - pyproject.toml: remove the uipath.governance.adapters entry point. - tests (test_adapter.py -> test_middleware.py): drop can_handle/attach/ detach; cover install_governance + factory wiring. ruff + mypy clean; 14 governance tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Review findings (Viswa) for PR #361: - AFTER_MODEL / AFTER_TOOL now run inside a try/finally around call_next, so they still fire (audit + rules observe the turn) when the model or tool call raises. GovernanceBlockException from before_* still aborts before call_next; the underlying error still propagates after the finally. - Streaming AFTER_MODEL: on a streaming ChatContext, context.result is a ResponseStream after call_next (reading it yielded empty text). We now register a stream_result_hook so AFTER_MODEL runs on the finalized ChatResponse the framework assembles once the stream is consumed. - Drop the per-callbacks uuid trace_id (identical for every call); trace correlation is owned by the layer below, matching LangChain. Requires uipath-core >= 0.5.20 (removed trace_id from EvaluatorProtocol) — bumped. - Count llm/tool calls only after governance passes: a DENY raised before the bump, inflating the counter on blocked calls. - Cap _stringify output so an oversized tool result / message can't hand a multi-megabyte string to the evaluator. - Trailing newline (W292). Note: agents are not cached by the factory (each runtime gets a fresh instance to avoid concurrent-Workflow reuse), so the cached-agent re-attach concern does not apply here — the idempotency guard is only a double-install safety net. The PR description's entry-point claim is stale (factory-evaluator uses no governance entry-point) and will be corrected. Tests: added finally-on-error (model + tool), streaming result-hook, and no-inflation-on-block coverage. 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 Microsoft Agent Framework governance adapter to
uipath-agent-framework. It lets UiPath governance evaluate what anagent_frameworkagent does at the model and tool level, and block disallowed actions, without the agent author writing governance code. This package contains only the Agent-Framework-specific bridge.What it does
Detects an
agent_framework.BaseAgent(can_handleclaims only realBaseAgentinstances) and installs governance by prepending aChatMiddlewareand aFunctionMiddlewaretoagent.middleware(governance runs first; existing middleware is preserved). For workflow agents it installs on each inner agent.Each middleware brackets its call and maps to a governance check:
ChatMiddleware— before the model callBEFORE_MODELChatMiddleware— after the model callAFTER_MODELFunctionMiddleware— before the tool callTOOL_CALLFunctionMiddleware— after the tool callAFTER_TOOLEnforces 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.