feat(skills): add skills support to advanced agents with sandboxed cli tool - #989
Conversation
There was a problem hiding this comment.
Pull request overview
Adds initial “skills” plumbing to advanced agents and introduces a sandbox-oriented internal tool for running uip commands inside an agent workspace.
Changes:
- Introduces a new
create_uipath_cli_tool()(uipath_cli) StructuredTool that runs oneuipcommand per invocation with command validation. - Adds unit tests covering command parsing, validation, subprocess result mapping, and timeout behavior for the new tool.
- Extends advanced-agent builders to accept and forward a
skillsparameter into the underlying deepagents agent construction.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
tests/agent/tools/internal_tools/test_uipath_cli_tool.py |
Adds test coverage for the new sandboxed CLI tool. |
src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py |
Implements the sandboxed uipath_cli tool and its input/output schemas. |
src/uipath_langchain/agent/tools/internal_tools/__init__.py |
Exports create_uipath_cli_tool from the internal tools package. |
src/uipath_langchain/agent/advanced/agent.py |
Adds skills parameter propagation to deepagents agent creation/wrappers. |
d79b0c1 to
5b5dea8
Compare
5b5dea8 to
36f2b2c
Compare
36f2b2c to
2f7b1c1
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
src/uipath_langchain/agent/advanced/agent.py:45
- The
create_advanced_agentdocstring documentsmemorybut not the newly addedskillsparameter, which is part of the public API. Update the docstring to describe whatskillsdoes and how an empty value is handled.
"""Create a deepagents agent with planning, filesystem, and sub-agent tools.
``memory`` is a list of file paths loaded via deepagents' ``MemoryMiddleware``:
each is read from ``backend`` and injected into the system prompt every turn,
and the model maintains them with ``edit_file``. Empty disables the middleware.
"""
2f7b1c1 to
4922fb1
Compare
4922fb1 to
bff67ea
Compare
bff67ea to
df1cb80
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/uipath_langchain/agent/advanced/agent.py:42
create_advanced_agentnow acceptsskills, but the docstring only documentsmemory. Since empty skills collapses toNone(disabling skills support), documenting this behavior would help callers understand how to enable/disable the feature.
skills: Sequence[str] = (),
) -> CompiledStateGraph[Any, Any, Any, Any]:
"""Create a deepagents agent with planning, filesystem, and sub-agent tools.
``memory`` is a list of file paths loaded via deepagents' ``MemoryMiddleware``:
9bbae6c to
850386e
Compare
7d9ca46 to
b02dd2b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (3)
src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py:37
- The tool description says “A negative exit_code means the command was refused”. That’s inaccurate because real subprocess exit codes can be negative on Unix when terminated by a signal. The contract in UiPathCliOutput/test cases is specifically “exit_code == -1000 indicates refusal”, so the description should match to avoid confusing the agent.
"Run a single UiPath `uip` command in the agent workspace; returns "
"exit_code/stdout/stderr. Only the uip/uipath binaries, one command per call; "
"shell chaining is refused. A negative exit_code means the command was refused "
"before it ran and stderr explains why. Use `subdir` to target a scaffolded "
"project folder."
src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py:167
- On timeout, proc.kill() can raise ProcessLookupError if the process exits between the timeout firing and the kill call. That would crash the tool instead of returning the recoverable _REJECTED_EXIT_CODE payload.
except asyncio.TimeoutError:
proc.kill()
await proc.wait()
return _rejected(
echoed, f"Command timed out after {_COMMAND_TIMEOUT_SECONDS}s."
src/uipath_langchain/agent/advanced/agent.py:110
- This PR introduces a sandboxed uipath_cli tool, but create_advanced_agent only forwards the
skillslist into deepagents and never registers the new tool. The new tool module’s docstring says it is “injected programmatically by the agent graph builder when UiPath skills are active”, but there is currently no call site for create_uipath_cli_tool in src/ (verified by repo search). If skills are expected to prescribeuipcommands, the agent needs the tool added to its tool list when skills are enabled (and a FilesystemBackend workspace exists).
memory=list(memory) or None,
middleware=list(middleware),
skills=list(skills) if skills else None,
b02dd2b to
4083836
Compare
4083836 to
b8d13be
Compare
817b196 to
e88d052
Compare
6ddc4c3 to
8eb9b84
Compare
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8eb9b84 to
6c54ba9
Compare
|



Title: Uipath Skills with Cli tool for advanced agents.
Summary
Adds skills feature for advanced agents. Agent can act on it — run uip commands, review what it ran, and verify what it scaffolded.
The feature flag exists for low-code graph builder reached only via
agent.json→AgentsRuntimeFactory→_build_advanced_agent.Coded agents resolve to a different runtime factory (
langgraph.json) and never evaluate that flag. A coded author who writes:from uipath_langchain.agent.tools.internal_tools import create_uipath_cli_toolgets full
uipexecution with no kill switch at this layer.If you are adding this tool to a coded agent and need destructive commands restricted, wrap it with your own validation before handing it to the agent. Do not rely on a tool-level
@guardrail, which does not fire for this tool.For example, delegate to the tool from your own
StructuredToolthat rejects the commands you careabout, and apply platform guardrails at the agent/graph level rather than the tool level.