Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added samples/openai-sdk-agent/.DS_Store
Binary file not shown.
560 changes: 560 additions & 0 deletions samples/openai-sdk-agent/.agent/CLI_REFERENCE.md

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions samples/openai-sdk-agent/.agent/REQUIRED_STRUCTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
## Required Agent Structure

**IMPORTANT**: All UiPath coded agents MUST follow this standard structure unless explicitly specified otherwise by the user.

### Required Components

Every agent implementation MUST include these two Pydantic models:

```python
from pydantic import BaseModel

class Input(BaseModel):
"""Define input fields that the agent accepts"""
# Add your input fields here
pass

class Output(BaseModel):
"""Define output fields that the agent returns"""
# Add your output fields here
pass
```

### SDK Initialization

```python
from uipath.platform import UiPath

# Initialize with environment variables
uipath = UiPath()

# With explicit credentials
uipath = UiPath(base_url="https://cloud.uipath.com/...", secret="your_token")

# Or with client_id and client_secret
uipath = UiPath(
client_id=UIPATH_CLIENT_ID,
client_secret=UIPATH_CLIENT_SECRET,
scope=UIPATH_SCOPE,
base_url=UIPATH_URL
)
```

### Standard Agent Template

Every agent should follow this basic structure:

```python
from uipath.platform import UiPath
from pydantic import BaseModel

# 1. Define Input, and Output models
class Input(BaseModel):
field: str

class Output(BaseModel):
result: str

# 2. Initialize with environment variables
uipath = UiPath()

# 3. Define the main function (the main function can be named "main", "run" or "execute")
def main(input_data: Input) -> Output:
pass
```
637 changes: 637 additions & 0 deletions samples/openai-sdk-agent/.agent/SDK_REFERENCE.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions samples/openai-sdk-agent/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Agent Code Patterns Reference

This document provides practical code patterns for building UiPath coded agents using the UiPath Python SDK.

---

## Documentation Structure

This documentation is split into multiple files for efficient context loading. Load only the files you need:

1. **@.agent/REQUIRED_STRUCTURE.md** - Agent structure patterns and templates
- **When to load:** Creating a new agent or understanding required patterns
- **Contains:** Required Pydantic models (Input, Output), SDK initialization patterns, standard agent template

2. **@.agent/SDK_REFERENCE.md** - Complete SDK API reference
- **When to load:** Calling UiPath SDK methods, working with services (actions, assets, jobs, etc.)
- **Contains:** All SDK services and methods with full signatures and type annotations

3. **@.agent/CLI_REFERENCE.md** - CLI commands documentation
- **When to load:** Working with `uipath init`, `uipath run`, or `uipath eval` commands
- **Contains:** Command syntax, options, usage examples, and workflows
1 change: 1 addition & 0 deletions samples/openai-sdk-agent/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
Empty file.
4 changes: 4 additions & 0 deletions samples/openai-sdk-agent/bindings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"version": "2.0",
"resources": []
}
15 changes: 15 additions & 0 deletions samples/openai-sdk-agent/entry-points.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://cloud.uipath.com/draft/2024-12/entry-point",
"$id": "entry-points.json",
"entryPoints": [
{
"filePath": "main",
"uniqueId": "3b556e17-b54b-4b5f-b734-0ebee4fa3f82",
"type": "agent",
"input": {},
"output": {
"type": "object"
}
}
]
}
3 changes: 3 additions & 0 deletions samples/openai-sdk-agent/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"message": "Check the weather forecast for New York City for the next 3 days."
}
107 changes: 107 additions & 0 deletions samples/openai-sdk-agent/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import asyncio

import dotenv
from agents import Agent, RawResponsesStreamEvent, Runner, trace
from openai.types.responses import ResponseContentPartDoneEvent, ResponseTextDeltaEvent
from pydantic import BaseModel

from uipath.tracing import traced

dotenv.load_dotenv()

"""
This example shows the handoffs/routing pattern adapted for UiPath coded agents.
The triage agent receives the first message, and then hands off to the appropriate
agent based on the language of the request. Responses are streamed to the user.

Based on: https://github.com/openai/openai-agents-python/blob/main/examples/agent_patterns/routing.py
"""


# Required Input/Output models for UiPath coded agents
class Input(BaseModel):
"""Input model for the routing agent."""

message: str


class Output(BaseModel):
"""Output model for the routing agent."""

response: str
agent_used: str


# Define specialized agents for different languages
french_agent = Agent(
name="french_agent",
instructions="You only speak French",
)

spanish_agent = Agent(
name="spanish_agent",
instructions="You only speak Spanish",
)

english_agent = Agent(
name="english_agent",
instructions="You only speak English",
)

# Triage agent routes to appropriate language agent
triage_agent = Agent(
name="triage_agent",
instructions="Handoff to the appropriate agent based on the language of the request.",
handoffs=[french_agent, spanish_agent, english_agent],
)


@traced(name="Language Routing Agent Main")
async def main(input_data: Input) -> Output:
"""Main function to run the language routing agent.

Args:
input_data: Input model with a message for the agent.

Returns:
Output: Result containing the agent's response and which agent was used.
"""
print(f"\nProcessing message: {input_data.message}")

with trace("Language Routing Agent"):
# Run the agent with streaming
result = Runner.run_streamed(
triage_agent,
input=[{"content": input_data.message, "role": "user"}],
)

# Collect the response
response_parts = []
async for event in result.stream_events():
if not isinstance(event, RawResponsesStreamEvent):
continue
data = event.data
if isinstance(data, ResponseTextDeltaEvent):
print(data.delta, end="", flush=True)
response_parts.append(data.delta)
elif isinstance(data, ResponseContentPartDoneEvent):
print()

# Get the final response and agent used
final_response = "".join(response_parts)
agent_used = result.current_agent.name

print(f"\n\nAgent used: {agent_used}")
return Output(response=final_response, agent_used=agent_used)


if __name__ == "__main__":
# Example usage with different languages:
# 1. English message
# asyncio.run(main(Input(message="Hello, how are you?")))

# 2. French message
# asyncio.run(main(Input(message="Bonjour, comment allez-vous?")))

# 3. Spanish message
asyncio.run(main(Input(message="Hola, ¿cómo estás?")))
10 changes: 10 additions & 0 deletions samples/openai-sdk-agent/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[project]
name = "openai-sdk-agent"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"openai-agents>=0.6.4",
"uipath>=2.2.28",
]
100 changes: 100 additions & 0 deletions samples/openai-sdk-agent/test_uipath_openai.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""Test script to verify UiPath's OpenAI-compatible LLM Gateway."""

import os

from openai import OpenAI

try:
import dotenv

dotenv.load_dotenv()
except ImportError:
pass # dotenv not available, use environment variables directly

# Configure for UiPath
base_url = os.getenv("UIPATH_URL", "https://cloud.uipath.com")
access_token = os.getenv("UIPATH_ACCESS_TOKEN")

if not access_token:
print("❌ UIPATH_ACCESS_TOKEN not set in environment")
exit(1)

# Create OpenAI client pointing to UiPath
openai_base_url = f"{base_url.rstrip('/')}/orchestrator_/llm/openai"
print(f"Testing UiPath LLM Gateway at: {openai_base_url}")

client = OpenAI(
api_key=access_token,
base_url=openai_base_url,
)

# Test 1: List available models
print("\n1. Testing: List Models")
print("-" * 50)
try:
models = client.models.list()
print("✓ Success! Available models:")
for model in models.data:
print(f" - {model.id}")
except Exception as e:
print(f"❌ Error: {e}")

# Test 2: Simple chat completion
print("\n2. Testing: Chat Completion")
print("-" * 50)
try:
response = client.chat.completions.create(
model="gpt-4o-mini-2024-07-18",
messages=[
{"role": "user", "content": "Say 'Hello from UiPath!' and nothing else."}
],
max_tokens=50,
)
print(f"✓ Success! Response: {response.choices[0].message.content}")
print(f" Model used: {response.model}")
print(f" Tokens: {response.usage.total_tokens}")
except Exception as e:
print(f"❌ Error: {e}")

# Test 3: Chat completion with tool calling
print("\n3. Testing: Tool Calling")
print("-" * 50)
try:
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
},
"required": ["location"],
},
},
}
]

response = client.chat.completions.create(
model="gpt-4o-mini-2024-07-18",
messages=[{"role": "user", "content": "What's the weather in London?"}],
tools=tools,
max_tokens=100,
)

if response.choices[0].message.tool_calls:
print("✓ Success! Tool was called:")
for tool_call in response.choices[0].message.tool_calls:
print(f" - Function: {tool_call.function.name}")
print(f" - Arguments: {tool_call.function.arguments}")
else:
print(f"⚠ No tool calls. Response: {response.choices[0].message.content}")
except Exception as e:
print(f"❌ Error: {e}")

print("\n" + "=" * 50)
print("UiPath OpenAI LLM Gateway Test Complete")
print("=" * 50)
16 changes: 16 additions & 0 deletions samples/openai-sdk-agent/uipath.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://cloud.uipath.com/draft/2024-12/uipath",
"runtimeOptions": {
"isConversational": false
},
"packOptions": {
"fileExtensionsIncluded": [],
"filesIncluded": [],
"filesExcluded": [],
"directoriesExcluded": [],
"includeUvLock": true
},
"functions": {
"main": "main.py:main"
}
}
Loading