Skip to content

Commit b82bae8

Browse files
feat: design coded deepagents
1 parent d6b9227 commit b82bae8

25 files changed

Lines changed: 1081 additions & 17 deletions
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Review: Coded DeepAgents Contract And Sample
2+
3+
## TODOs
4+
- [x] T01 Determine review scope and initialize the workfile
5+
- [x] T02 Capture conventions and reuse baseline
6+
- [x] T03 Select review dimensions and spawn agents
7+
- [x] T04 Wait for every required review agent to complete
8+
- [x] T05 Synthesize findings into the workfile
9+
- [x] T06 Finalize the findings-first review output
10+
11+
## Scope
12+
13+
### Target Area
14+
- Staged diff for the DeepAgents coded-agent contract and sample.
15+
- Exact command: `git diff --cached -- src/uipath_langchain/deepagents src/uipath_langchain/agent/advanced/agent.py src/uipath_langchain/runtime/factory.py src/uipath_langchain/runtime/runtime.py tests/deepagents tests/agent/advanced/test_create_advanced_agent_graph.py samples/coded-deepagent samples/README.md`
16+
17+
### Entrypoints
18+
- `src/uipath_langchain/deepagents/agent.py`
19+
- `src/uipath_langchain/deepagents/backend.py`
20+
- `src/uipath_langchain/deepagents/metadata.py`
21+
- `src/uipath_langchain/runtime/factory.py`
22+
- `src/uipath_langchain/runtime/runtime.py`
23+
- `src/uipath_langchain/agent/advanced/agent.py`
24+
- `samples/coded-deepagent/graph.py`
25+
26+
### Main Behaviors Or Deltas
27+
- Adds public `uipath_langchain.deepagents` helpers for task-mode coded DeepAgents.
28+
- Tags graph builders/compiled graphs with `UiPathDeepAgentRuntimeSpec`.
29+
- Runtime factory detects tagged graphs, creates a workspace, injects workspace path into LangGraph config, and wraps the resumable runtime in `HydrationRuntime`.
30+
- Advanced agent wrappers now forward `subagents`.
31+
- Adds a task-mode sample using typed input/output, a tool, a review subagent, and the runtime workspace contract.
32+
33+
### Primary Risks To Examine
34+
- Public interface compatibility and whether the new helper exposes DeepAgents semantics accurately.
35+
- Runtime behavior around graph caching, workspace lifecycle, hydration scope, and config injection.
36+
- Whether sample dependencies and import-time behavior match existing sample conventions.
37+
- Test coverage for the public contract and runtime wrapping.
38+
- Abstraction cost from adding a new package and metadata side channel.
39+
40+
## Conventions Baseline
41+
- Naming and file placement: runtime integrations live under `src/uipath_langchain/runtime`; author-facing agent helpers live under `src/uipath_langchain/agent/*`; sample folders are under `samples/<name>` with `graph.py`, `langgraph.json`, `uipath.json`, `pyproject.toml`, `README.md`, and optional `agent.mermaid`.
42+
- Validation and error handling: runtime factory maps load/compile errors into `LangGraphRuntimeError`; feature gaps in author helpers use explicit `NotImplementedError`.
43+
- Testing and verification: focused unit tests live under `tests/<area>` and often inspect runtime wrapper internals directly with mocks; async runtime tests use pytest asyncio.
44+
- Reuse seams to preserve: `create_advanced_agent` remains the local DeepAgents wrapper; runtime config is built centrally in `UiPathLangGraphRuntime._get_graph_config`; graph metadata helpers should avoid LangGraph internals where possible.
45+
- Abstraction and ownership style: small helper modules are acceptable when they isolate contracts (`metadata`) or runtime-specific adaptation (`backend`), but pass-through wrappers should earn their keep by clarifying UiPath semantics.
46+
47+
## Selected Review Dimensions
48+
49+
| Dimension | Status | Reason |
50+
| --------- | ------ | ------ |
51+
| Correctness | reviewed | Runtime hydration and backend factory behavior have execution-path gaps. |
52+
| Architecture | reviewed | New public package and runtime wrapper are reasonable, but workspace-capability signaling is incomplete. |
53+
| Data Contracts | reviewed | Runtime spec exposes persistence fields, but author helpers do not expose/choose the right success persistence policy. |
54+
| Testing | reviewed | Added unit coverage verifies tagging/config injection, but not success dehydration or runtime factory backend edge cases. |
55+
| Maintainability | reviewed | New modules are small and readable; unresolved behavior should be made explicit in the contract. |
56+
| Conventions & Reuse | reviewed | Reuses existing advanced-agent and runtime seams, but the backend factory conflicts with existing filesystem-only checks. |
57+
| Security | skipped | No new auth, command execution, user-controlled file path trust boundary beyond existing runtime workspace APIs. |
58+
| Performance | skipped | No hot path or large-data loop; runtime wrapping is per-runtime creation. |
59+
60+
## Review Journal - By File
61+
62+
### `src/uipath_langchain/deepagents/agent.py`
63+
- Adds author-facing helper functions, task-mode guardrails, default backend factory, response format defaulting, and metadata tagging.
64+
- Simplicity note: wraps `create_advanced_agent_graph` to give UiPath-specific runtime semantics and metadata.
65+
66+
### `src/uipath_langchain/deepagents/backend.py`
67+
- Adds a DeepAgents backend factory that reads a runtime-injected configurable workspace path and returns a `FilesystemBackend`.
68+
- Simplicity note: small adapter around LangGraph tool runtime config.
69+
70+
### `src/uipath_langchain/deepagents/metadata.py`
71+
- Adds `UiPathDeepAgentRuntimeSpec` and helpers for attaching/retrieving it on graph-like objects.
72+
- Simplicity note: uses object attributes as an out-of-band metadata channel.
73+
74+
### `src/uipath_langchain/runtime/factory.py`
75+
- Preserves governance callback behavior while adding DeepAgents metadata propagation, workspace creation, config injection, and hydration wrapping.
76+
- Simplicity note: runtime creation now has an extra conditional wrapping path for tagged graphs.
77+
78+
### `src/uipath_langchain/runtime/runtime.py`
79+
- Adds optional `configurable` values merged into LangGraph run config.
80+
- Simplicity note: direct extension point for runtime-injected config.
81+
82+
### `src/uipath_langchain/agent/advanced/agent.py`
83+
- Adds `subagents` pass-through for task and conversational advanced wrappers.
84+
- Simplicity note: preserves existing wrapper responsibility while exposing an already supported DeepAgents parameter.
85+
86+
### `samples/coded-deepagent/*`
87+
- Adds a task-mode sample using the new contract, `UiPathChat`, a tool, subagent, input JSON, configs, README, and Mermaid diagram.
88+
- Simplicity note: sample intentionally avoids custom bucket backend so runtime contract is the visible path.
89+
90+
## Executive Summary
91+
92+
**Analysis:** Independent reviewer completed. The design is close, but two contract gaps mean the sample is not ready as-is.
93+
94+
| Dimension | Agent | Grade |
95+
|-----------|-------|-------|
96+
| Correctness | independent-reviewer | C |
97+
| Architecture | independent-reviewer | C |
98+
| Data Contracts | independent-reviewer | C |
99+
| Testing | independent-reviewer | C |
100+
| Maintainability | independent-reviewer | B |
101+
| Conventions & Reuse | independent-reviewer | B |
102+
| Security | skipped | N/A |
103+
| Performance | skipped | N/A |
104+
| **Overall** || **Needs Work** |
105+
106+
**Top Risks:** Successful task-mode workspace files are not persisted with the default hydration policy; runtime-backed DeepAgents do not get the existing filesystem-only memory and input-attachment behavior.
107+
108+
**Recommendations Priority:** Fix persistence policy first, then either make the runtime workspace backend participate in filesystem semantics or explicitly narrow the public contract.
109+
110+
**Confidence:** Medium-high. Findings were confirmed against the staged diff and the installed `uipath.runtime.HydrationRuntime` source.
111+
112+
**Verdict:** Needs Work.
113+
114+
## Code Quality Rubric (0-3)
115+
116+
| Criterion | Score | Evidence | Note |
117+
| --------- | ----- | -------- | ---- |
118+
| Single responsibility | 2 | `deepagents` modules isolate authoring, backend, and metadata helpers. | Good shape; runtime factory has the expected conditional wrapping branch. |
119+
| Boundaries & validation | 1 | Runtime spec allows hydration policy, but author helper does not expose it and defaults to non-success persistence. | Contract gap affects sample behavior. |
120+
| Typed contracts | 2 | Pydantic runtime spec and sample input/output schemas are clear. | More fields should be surfaced in helper API. |
121+
| Error taxonomy | 2 | Unsupported conversation modes are explicit `NotImplementedError`. | No issue found in new error handling. |
122+
| Determinism & state | 1 | `suspend_only` plus cleanup workspace loses successful task files. | High correctness risk. |
123+
| Algorithmic sanity | 2 | Config injection and metadata propagation are straightforward. | Needs backend factory path alignment. |
124+
| Naming & docs | 2 | Names are readable and sample explains the intended contract. | Docs currently overpromise success persistence. |
125+
| Minimal abstractions | 2 | New helpers are small. | Backend marker/capability abstraction may now be needed. |
126+
| Testability seams | 1 | Tests cover config/tagging, not success dehydration or factory-backed attachments/memory. | Add integration-style unit tests. |
127+
| Control flow clarity | 2 | Runtime wrapping path is understandable. | No major readability issue. |
128+
| Conventions & reuse | 2 | Reuses advanced agent wrapper and runtime config seams. | Filesystem-only conventions need updating for factories. |
129+
130+
## Architecture & Behavior
131+
132+
Retained for the final review because the change crosses authoring API, LangGraph runtime creation, and workspace hydration boundaries. A real diagram will be added only if it clarifies a finding or final risk.
133+
134+
## Findings Catalog
135+
136+
### High - Successful task-mode workspace files are not persisted
137+
138+
- Evidence: `UiPathDeepAgentRuntimeSpec.hydration_policy` defaults to `suspend_only` in `src/uipath_langchain/deepagents/metadata.py:22-27`.
139+
- Evidence: `create_uipath_deep_agent_graph` constructs the runtime spec without exposing a `hydration_policy` override in `src/uipath_langchain/deepagents/agent.py:79-130`.
140+
- Evidence: runtime factory passes `HydrationPolicy(spec.hydration_policy)` into `HydrationRuntime` in `src/uipath_langchain/runtime/factory.py:347-362`.
141+
- Evidence: installed `HydrationRuntime._should_dehydrate` only persists successful results for `SUSPEND_OR_SUCCESS`; `SUSPEND_ONLY` persists suspended results only.
142+
- Impact: The sample asks the agent to write `/launch/brief.md` and `/launch/risks.md`, then return those paths. On a normal successful task run, those files are not uploaded/linked as job attachments before `Workspace.create(..., cleanup=True)` cleanup.
143+
- Recommendation: Make task-mode DeepAgent helpers default to `suspend_or_success`, or expose `hydration_policy` and set the sample to success persistence. Add a success-path dehydration test.
144+
145+
### Medium - Runtime workspace backend factory bypasses existing FilesystemBackend behavior
146+
147+
- Evidence: `create_uipath_deep_agent_graph` defaults `backend` to `create_workspace_backend_factory(...)` in `src/uipath_langchain/deepagents/agent.py:106-108`.
148+
- Evidence: `create_advanced_agent_graph` only enables memory when `isinstance(backend, FilesystemBackend)` in `src/uipath_langchain/agent/advanced/agent.py:75-77`.
149+
- Evidence: `resolve_input_attachments` rejects non-`FilesystemBackend` backends in `src/uipath_langchain/agent/advanced/utils.py:58-72`, while `transform_input_async` passes the backend value directly.
150+
- Impact: Default UiPath DeepAgents do not load `/memory/MEMORY.md` through `MemoryMiddleware`, and attachment-shaped inputs fail before the runtime-injected backend factory can resolve a concrete filesystem backend.
151+
- Recommendation: Add an explicit runtime-workspace backend capability/marker that the advanced wrapper can use for memory and attachment resolution, or document that runtime-backed helpers do not support workspace memory/input attachments yet.
152+
153+
## Suggested Tests / Micro-Repros
154+
155+
- Success-path hydration: run a tagged DeepAgent runtime that writes a file and returns `SUCCESSFUL`; assert `WorkspaceHydrator.dehydrate` uploads/links the file under `suspend_or_success`.
156+
- Backend factory memory: build a runtime-backed DeepAgent with `/memory/MEMORY.md`; assert `MemoryMiddleware` is configured for the runtime workspace backend.
157+
- Backend factory input attachment: use an input schema with job attachment fields and the runtime workspace backend; assert attachments are downloaded into the injected workspace path.
158+
159+
## Fix Loop Result
160+
161+
- Resolved the High persistence issue by defaulting UiPath DeepAgents task-mode hydration to `suspend_or_success` and exposing `hydration_policy` on the authoring helpers.
162+
- Resolved the prior Medium backend-factory behavior by marking the UiPath runtime workspace backend factory as filesystem-workspace capable, enabling memory for that factory, and resolving attachment downloads through runtime `RunnableConfig`.
163+
- Added tests for default success persistence metadata, explicit hydration-policy propagation, marked runtime workspace factory resolution, memory enablement, and attachment resolution through the marked factory.
164+
- Independent reviewer `019f46ec-1dfd-7210-b220-2d498891fc8a` reported: `No Major/High/Critical blockers found`.
165+
- Remaining lower-severity notes from that review: reject reserved `workspace_config_key` values such as `thread_id`; add an execution-path test that writes a workspace file and asserts default `suspend_or_success` dehydration/upload.
166+
- Verification run: `uv run pytest --no-cov tests/deepagents tests/agent/advanced/test_memory_injection.py tests/agent/advanced/test_utils.py tests/agent/advanced/test_create_advanced_agent_graph.py tests/agent/advanced/test_conversational_advanced_agent_graph.py` passed with 29 tests.
167+
- Verification run: `uv run pytest --no-cov tests/deepagents tests/agent/advanced/test_create_advanced_agent_graph.py tests/agent/advanced/test_memory_injection.py tests/agent/advanced/test_utils.py tests/runtime/test_factory_governance.py tests/runtime/test_runtime_unit.py tests/runtime/test_reference_context_wiring.py` passed with 82 tests.
168+
- Verification run: `uv run ruff check` on touched Python files and the sample graph passed.
169+
- Verification run: `uv run ruff format --check` on touched Python files passed.
170+
171+
## Deferred Items
172+
- Full live execution of the sample requires UiPath credentials and model access.
173+
174+
## Changelog
175+
- 2026-07-09 Initialized workfile with staged-diff scope, conventions baseline, selected dimensions, and pending review status.
176+
- 2026-07-09 Added independent reviewer findings, verified hydration behavior, and finalized review verdict.
177+
- 2026-07-09 Ran fix loop, patched the High issue and backend-factory behavior, verified locally, and recorded no remaining Major+ blockers from independent review.

samples/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ This sample demonstrates a simple LangGraph agent that performs basic arithmetic
66
## [Chat agent](chat-agent)
77
This sample shows how to build an AI assistant using LangGraph and Tavily search for movie research and recommendations.
88

9+
## [Coded DeepAgent](coded-deepagent)
10+
This sample demonstrates a task-mode coded DeepAgent using the UiPath runtime workspace contract, typed input/output, a tool, and a review subagent.
11+
912
## [Company research agent](company-research-agent)
1013
This sample demonstrates how to create an agent that researches companies and develops outreach strategies using web search capabilities.
1114

samples/coded-deepagent/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Coded DeepAgent
2+
3+
This sample demonstrates a task-mode coded agent built with the UiPath
4+
DeepAgents contract.
5+
6+
The graph uses `create_uipath_deep_agent_graph`, which tags the graph for the
7+
UiPath LangGraph runtime. At runtime, UiPath creates a workspace, injects its
8+
path into LangGraph config, and hydrates that workspace through job
9+
attachments. Task-mode DeepAgents persist workspace changes when the run
10+
successfully completes or suspends. The sample does not configure a custom
11+
bucket backend.
12+
13+
## What It Shows
14+
15+
- Typed coded-agent input and output with Pydantic models.
16+
- A standard LangChain tool used by the main DeepAgent.
17+
- A DeepAgents subagent used for risk review.
18+
- Runtime-provided workspace persistence through the UiPath contract.
19+
20+
## Files
21+
22+
- `graph.py`: task-mode coded DeepAgent graph.
23+
- `input.json`: sample input payload.
24+
- `langgraph.json`: LangGraph entrypoint.
25+
- `uipath.json`: UiPath task-mode runtime configuration.
26+
- `agent.mermaid`: high-level graph diagram.
27+
28+
## Requirements
29+
30+
- UiPath runtime credentials for `UiPathChat`.
31+
- Access to the configured model, `gpt-4o-2024-08-06`.
32+
33+
## Run
34+
35+
```bash
36+
cd samples/coded-deepagent
37+
uv sync
38+
uipath run agent "$(cat input.json)"
39+
```
40+
41+
The agent writes `/launch/brief.md` and `/launch/risks.md` in the DeepAgents
42+
workspace and returns those paths in `workspace_files`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
flowchart TB
2+
__start__(__start__)
3+
transform_input(transform_input)
4+
advanced_agent(advanced_agent)
5+
risk_reviewer([risk_reviewer subagent])
6+
workspace[(runtime workspace)]
7+
transform_output(transform_output)
8+
__end__(__end__)
9+
10+
__start__ --> transform_input
11+
transform_input --> advanced_agent
12+
advanced_agent -. delegates review .-> risk_reviewer
13+
advanced_agent -. writes files .-> workspace
14+
advanced_agent --> transform_output
15+
transform_output --> __end__

samples/coded-deepagent/graph.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""Task-mode coded DeepAgent using the UiPath DeepAgents contract."""
2+
3+
from langchain_core.tools import tool
4+
from pydantic import BaseModel, Field
5+
6+
from uipath_langchain.chat import UiPathChat
7+
from uipath_langchain.deepagents import create_uipath_deep_agent_graph
8+
9+
10+
class BriefInput(BaseModel):
11+
"""Input for the product launch brief."""
12+
13+
product_name: str = Field(description="Name of the product or feature.")
14+
audience: str = Field(description="Primary customer or user audience.")
15+
objective: str = Field(description="Main launch objective.")
16+
constraints: list[str] = Field(
17+
default_factory=list,
18+
description="Important limits, requirements, or risks to account for.",
19+
)
20+
21+
22+
class BriefOutput(BaseModel):
23+
"""Structured launch brief returned by the agent."""
24+
25+
executive_summary: str
26+
launch_plan: list[str]
27+
risk_review: list[str]
28+
workspace_files: list[str]
29+
30+
31+
@tool
32+
def score_launch_readiness(audience: str, constraints: list[str]) -> str:
33+
"""Score launch readiness from simple deterministic planning signals."""
34+
score = 80
35+
if len(constraints) >= 3:
36+
score -= 10
37+
if any("compliance" in item.lower() for item in constraints):
38+
score -= 10
39+
if any("deadline" in item.lower() for item in constraints):
40+
score -= 5
41+
return f"Launch readiness for {audience}: {max(score, 35)}/100"
42+
43+
44+
MODEL = UiPathChat(model="gpt-4o-2024-08-06", temperature=0)
45+
46+
RISK_REVIEWER_PROMPT = """You are a launch risk reviewer.
47+
Review the proposed launch plan for practical delivery risks, compliance gaps,
48+
unclear ownership, and missing follow-up work. Return concise findings that the
49+
main agent can incorporate into the final brief."""
50+
51+
RISK_REVIEWER = {
52+
"name": "risk_reviewer",
53+
"description": "Reviews launch plans for execution risks and missing safeguards.",
54+
"system_prompt": RISK_REVIEWER_PROMPT,
55+
"model": MODEL,
56+
}
57+
58+
SYSTEM_PROMPT = """You are a product launch planning agent.
59+
60+
Use the planning tools provided by DeepAgents. Use score_launch_readiness to get
61+
a deterministic readiness signal. Delegate a plan review to risk_reviewer before
62+
finalizing the answer.
63+
64+
The UiPath runtime provides your DeepAgents filesystem through the tagged graph
65+
contract. Write these workspace files before producing the final answer:
66+
- /launch/brief.md with the final launch brief
67+
- /launch/risks.md with the risk review
68+
69+
Return structured output matching the schema. Include the workspace file paths
70+
you wrote in workspace_files."""
71+
72+
73+
def build_user_message(args: dict) -> str:
74+
constraints = args.get("constraints") or []
75+
constraint_lines = "\n".join(f"- {item}" for item in constraints) or "- None"
76+
return f"""Create a launch brief.
77+
78+
Product: {args["product_name"]}
79+
Audience: {args["audience"]}
80+
Objective: {args["objective"]}
81+
Constraints:
82+
{constraint_lines}
83+
"""
84+
85+
86+
graph = create_uipath_deep_agent_graph(
87+
model=MODEL,
88+
input_schema=BriefInput,
89+
output_schema=BriefOutput,
90+
system_prompt=SYSTEM_PROMPT,
91+
tools=[score_launch_readiness],
92+
subagents=[RISK_REVIEWER],
93+
build_user_message=build_user_message,
94+
)

0 commit comments

Comments
 (0)