Skip to content

chore: add template agent#719

Open
radu-mocanu wants to merge 1 commit intomainfrom
chore/add-template-agent
Open

chore: add template agent#719
radu-mocanu wants to merge 1 commit intomainfrom
chore/add-template-agent

Conversation

@radu-mocanu
Copy link
Collaborator

  • add template agent

Why

This agent will be dynamically fetch by StudioWeb and exposed as a template.

Copy link
Collaborator

Choose a reason for hiding this comment

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

should we also add a custom evaluator?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new “template agent” project intended to be dynamically fetched by StudioWeb and used as a starter template for UiPath LangGraph agents.

Changes:

  • Introduces a full template agent project (graph code, config, entry points, bindings, sample input).
  • Adds evaluation assets (tool-call-order evaluator + default evaluation set).
  • Adds bundled template documentation (.agent references and README).

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
template/main.py Implements the template agent graph (prepare → react agent → optional refinement).
template/README.md Documents agent behavior, tools, graph flow, and local run/eval commands.
template/pyproject.toml Template project metadata and dependencies.
template/langgraph.json Declares the exported graph entrypoint.
template/uipath.json Runtime/pack options for the template project.
template/project.uiproj Declares the project as an Agent project.
template/input.json Example input payload for local runs.
template/entry-points.json Declares agent entrypoint schema and graph metadata for StudioWeb.
template/bindings.json Resource bindings placeholder.
template/agent.mermaid Mermaid diagram of the agent + subgraph.
template/evaluations/evaluators/tool-call-order-1774285735846.json Tool call order evaluator definition.
template/evaluations/eval-sets/evaluation-set-default.json Default evaluation set referencing the tool-call-order evaluator.
template/evaluations/evaluators/evaluator-default.json Default “contains” evaluator definition (currently misaligned with template output).
template/AGENTS.md Index doc pointing to .agent references.
template/CLAUDE.md References AGENTS.md for context loading.
template/.agent/REQUIRED_STRUCTURE.md Documents the required agent code structure/patterns.
template/.agent/SDK_REFERENCE.md SDK reference documentation bundle.
template/.agent/CLI_REFERENCE.md CLI reference documentation bundle.

from uipath_langchain.chat.vertex import UiPathChatVertex
SYSTEM_PROMPT = (
"You are a helpful assistant. "
"Answer the user's query using the available tools when needed."
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

SYSTEM_PROMPT string concatenation is missing a space between sentences, so the rendered prompt becomes "...when needed.Be concise...". Add a trailing space to the previous fragment or a leading space to the next one to keep the prompt readable.

Suggested change
"Answer the user's query using the available tools when needed."
"Answer the user's query using the available tools when needed. "

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +69
async def prepare(input: InputModel) -> dict:
return {
"messages": [
SystemMessage(SYSTEM_PROMPT),
HumanMessage(input.query),
],
"refine": input.refine,
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

prepare is added as a node in a StateGraph(StateModel, input=InputModel, output=OutputModel), but the node signature currently accepts InputModel rather than StateModel (or a dict update). This will not match the state type LangGraph passes to nodes in this graph; refactor prepare to accept the state and return state updates (or restructure to follow the standard Input->State pattern).

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +76
react_agent = create_agent(
model=UiPathChatOpenAI(model_name=OpenAIModels.gpt_4_1_mini_2025_04_14),
tools=[get_current_time, web_search],
response_format=AgentResponse,
)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

create_agent(...) is called with response_format=AgentResponse, but there are no other usages in this repo that pass response_format to langchain.agents.create_agent, and it is likely not a supported parameter (will raise TypeError: got an unexpected keyword argument). Consider removing it and extracting the final answer from the last AI message, or switching to an agent builder that supports structured output explicitly.

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +99
async def refine(state: StateModel) -> dict:
"""Optionally refine the agent response using a quality reviewer."""
if state.refine and not state.was_refined:
suggestion = await UiPathChatVertex(model_name=GeminiModels.gemini_2_5_flash).with_structured_output(RefinementSuggestion).ainvoke(
[
SystemMessage(
"You are a quality reviewer. Based on the topic and the current response, "
"suggest one specific improvement to make the answer more accurate or complete."
),
HumanMessage(
f"Topic: {state.messages[1].content}\n"
f"Current response: {state.structured_response['response']}"
),
]
)
return {
"messages": [HumanMessage(f"Refinement suggestion: {suggestion.suggestion}")],
"was_refined": True,
}
return {"result": state.structured_response["response"]}

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

StateModel.structured_response is never populated anywhere in this graph (searching the repo shows no other code setting it), but refine reads state.structured_response['response'] and later returns state.structured_response["response"]. This will fail at runtime when structured_response is None; either set structured_response from the agent output, or derive the response from state.messages[-1].content instead.

Copilot uses AI. Check for mistakes.
return {"result": state.structured_response["response"]}


def route(state: StateModel) -> Literal["react_agent", END]:
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

route uses a Literal["react_agent", END] return type, but END is a runtime constant rather than a literal value. For typing correctness (and consistency with other code in this repo), use the string end node id (e.g. "__end__") in the Literal[...] or just annotate as str.

Suggested change
def route(state: StateModel) -> Literal["react_agent", END]:
def route(state: StateModel) -> str:

Copilot uses AI. Check for mistakes.
name = "uipath-langchain-template-agent"
version = "0.0.1"
description = "uipath-langchain-template-agent"
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

pyproject.toml still contains placeholder author metadata ("John Doe", "john.doe@myemail.com"). For a published template this is misleading; please replace with your organization/team info or remove the authors field entirely.

Suggested change
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +13
"evaluatorConfig": {
"name": "Default Contains Evaluator",
"targetOutputKey": "output",
"negated": false,
"ignoreCase": false,
"defaultEvaluationCriteria": {
"searchText": "expected text"
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

This evaluator config uses targetOutputKey: "output", but the template agent's declared output schema uses the result key (see entry-points.json and OutputModel). If this evaluator is intended to be used, it will look at the wrong field; update it to result or remove the unused default evaluator to avoid confusion.

Copilot uses AI. Check for mistakes.
Comment on lines +185 to +217
### Configuration File (uipath.json)

The `uipath.json` file is automatically generated by `uipath init` and defines your agent's schema and bindings.

**Structure:**

```json
{
"entryPoints": [
{
"filePath": "agent",
"uniqueId": "uuid-here",
"type": "agent",
"input": {
"type": "object",
"properties": { ... },
"description": "Input schema",
"required": [ ... ]
},
"output": {
"type": "object",
"properties": { ... },
"description": "Output schema",
"required": [ ... ]
}
}
],
"bindings": {
"version": "2.0",
"resources": []
}
}
```
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The CLI reference section documents a uipath.json structure that includes entryPoints and bindings, but this template uses separate entry-points.json and bindings.json files (and uipath.json only contains runtime/pack options). Please update this doc section to reflect the actual template layout so users don’t regenerate/modify the wrong files.

Copilot uses AI. Check for mistakes.
@CatalinB7
Copy link

pls don't forget about .uipath/studio-metadata.json

Also another discussion to have (for later): is fetching files from github is always possible from SW (eg github might be down - what's the fallback)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants