# Build UiPath Agents

Implement agent logic using UiPath SDK and framework-specific patterns.

## Reference Lookup

Read **only** the reference matching the selected framework. Do NOT load other framework references.

| Framework | Reference |
|-----------|-----------|
| LangGraph | `../frameworks/langgraph-integration.md` |
| LlamaIndex | `../frameworks/llamaindex-integration.md` |
| OpenAI Agents | `../frameworks/openai-agents-integration.md` |

Load capability references **only if the task requires them** — do not preload:

| Capability | Reference | Load when... |
|------------|-----------|-------------|
| RPA process invocation | `../capabilities/process-invocation.md` | agent invokes UiPath processes/jobs |
| Human approval / interrupt | `../capabilities/human-in-the-loop.md` | agent needs human-in-the-loop or pause/resume |
| RAG / context grounding | `../capabilities/context-grounding.md` | agent searches organization documents |
| Platform API calls | `../capabilities/sdk-services.md` | agent uses UiPath platform services directly |
| Tracing / monitoring | `../capabilities/tracing.md` | agent needs custom tracing (Coded Function only — LangGraph traces automatically) |
| File attachments (input or created) | `../capabilities/file-attachments.md` | agent takes a file as input, or creates an attachment |
| Conversational (chat-style) agents | `../capabilities/conversational-agents.md` | agent receives one message per turn; runtime threads history (LangGraph / LlamaIndex only) |

## Framework Reference

| Framework | Config File | Key Dependency | Entry Point |
|-----------|------------|----------------|-------------|
| Coded Function | `uipath.json` | `uipath` | `main.py` function |
| LangGraph | `langgraph.json` | `uipath-langchain` | `main.py` compiled StateGraph |
| LlamaIndex | `llama_index.json` | `uipath-llamaindex` | `main.py` Workflow instance |
| OpenAI Agents | `openai_agents.json` | `uipath-openai-agents` | `main.py` Agent instance |

## Troubleshooting

| Error | Cause | Solution |
|-------|-------|----------|
| `'dict' has no attribute '...'` | `with_structured_output()` returns a dict, not a Pydantic model | Access results with `result['key']` dict syntax, not `result.key` attribute access |
| `ImportError: Could not import <package>` | External tool package not in `pyproject.toml` | Add all third-party tool packages to dependencies: `uv add <package>` |
| Agent returns empty output | Entry point not wired correctly | Verify `main.py` exports the correct object (compiled graph, Workflow, Agent) |
| `TypeError` on Input/Output | Schema mismatch after code change | Re-run `uip codedagent init` to regenerate `entry-points.json` |

## Additional Instructions

- **File/document input → `Attachment`, never a filesystem path string.** If the prompt says the agent "takes a CSV/PDF/file as input" (or similar), read `../capabilities/file-attachments.md` before defining the `Input` model. A `str` path field runs locally with `uip codedagent run` but breaks on Studio Web/Orchestrator, where no such path exists in the container.
- **Select a framework before writing any code.** Infer from the prompt if possible (tools/orchestration → LangGraph, RAG → LlamaIndex, simple LLM → OpenAI Agents, no LLM → Coded Function). If ambiguous, ask the user to choose.
- **Structured input contract → not OpenAI Agents.** OpenAI Agents always require a `messages` input field and cannot express an input contract without it (see `../frameworks/openai-agents-integration.md` § Input). When the user needs a strict typed/structured input (e.g. a single named field, no `messages`), choose LangGraph (custom `StateGraph` with arbitrary input state) instead. Do NOT silently fall back to a Coded Function to satisfy the input shape — a Coded Function produces `ProjectType: Function`, not a coded agent, so it does not fulfill a request for an agent.
- **Read ONLY the single framework reference** for the selected framework before writing code. Do NOT read other framework references or capability references unless the task explicitly requires that capability.
- **Clean generated scaffold code before schema init.** After `uip codedagent new` and before running `uip codedagent init`, inspect `main.py` and remove scaffold hazards: no module-level `UiPathChat`, `UiPathAzureChatOpenAI`, `UiPath`, or other auth-dependent clients; instantiate LLM/SDK clients inside graph nodes/functions only; ensure importing `main.py` works without UiPath auth.
- **NEVER instantiate LLM clients or SDK clients at module level.** `uip codedagent init` imports your Python file to introspect schemas — module-level `UiPathAzureChatOpenAI()`, `UiPathChat()`, `UiPathChatOpenAI()`, or `UiPath()` will fail because auth may not have happened yet. Always create these instances inside functions or graph nodes, never at the top level of the module.
- **Correct SDK import: `from uipath.platform import UiPath`** — not `from uipath import UiPath` (that does not exist). Instantiate inside functions only: `sdk = UiPath()`.
- LangGraph agents get tracing automatically — no `@traced()` needed on graph nodes.
- Simple function agents require `@traced()` on the `main` function.
