Skip to content

Commit 34cc429

Browse files
authored
Merge pull request #124 from UiPath/fix/openai_agents_refactoring
fix: refactor open ai code
2 parents 832f0a2 + 09bae07 commit 34cc429

30 files changed

Lines changed: 485 additions & 2111 deletions
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
22
"message": "Tell me a joke"
3-
}
3+
}
Lines changed: 58 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import dotenv
2-
from agents import Agent, AgentOutputSchema, Runner, trace
1+
from agents import Agent, AgentOutputSchema
2+
from agents.models import _openai_shared
33
from pydantic import BaseModel, Field
4-
from uipath.tracing import traced
54

6-
dotenv.load_dotenv()
5+
from uipath_openai_agents.chat import UiPathChatOpenAI
76

87
"""
98
This example shows the agents-as-tools pattern adapted for UiPath coded agents.
@@ -17,16 +16,6 @@
1716
"""
1817

1918

20-
# Required Input/Output models for UiPath coded agents
21-
class TranslationInput(BaseModel):
22-
"""Input model for the translation orchestrator."""
23-
24-
text: str = Field(description="The English text to translate")
25-
target_languages: list[str] = Field(
26-
description="List of target languages (e.g., ['Spanish', 'French', 'Italian'])"
27-
)
28-
29-
3019
class TranslationOutput(BaseModel):
3120
"""Output model for the translation orchestrator."""
3221

@@ -39,95 +28,63 @@ class TranslationOutput(BaseModel):
3928
)
4029

4130

42-
spanish_agent = Agent(
43-
name="spanish_agent",
44-
instructions="You translate the user's message to Spanish",
45-
handoff_description="An english to spanish translator",
46-
)
31+
def main() -> Agent:
32+
"""Configure UiPath OpenAI client and return the orchestrator agent."""
33+
# Configure UiPath OpenAI client for agent execution
34+
# This routes all OpenAI API calls through UiPath's LLM Gateway
35+
MODEL = "gpt-4o-2024-11-20"
36+
uipath_openai_client = UiPathChatOpenAI(model_name=MODEL)
37+
_openai_shared.set_default_openai_client(uipath_openai_client.async_client)
38+
39+
# Define specialized translation agents
40+
spanish_agent = Agent(
41+
name="spanish_agent",
42+
instructions="You translate the user's message to Spanish",
43+
handoff_description="An english to spanish translator",
44+
model=MODEL,
45+
)
4746

48-
french_agent = Agent(
49-
name="french_agent",
50-
instructions="You translate the user's message to French",
51-
handoff_description="An english to french translator",
52-
)
47+
french_agent = Agent(
48+
name="french_agent",
49+
instructions="You translate the user's message to French",
50+
handoff_description="An english to french translator",
51+
model=MODEL,
52+
)
5353

54-
italian_agent = Agent(
55-
name="italian_agent",
56-
instructions="You translate the user's message to Italian",
57-
handoff_description="An english to italian translator",
58-
)
54+
italian_agent = Agent(
55+
name="italian_agent",
56+
instructions="You translate the user's message to Italian",
57+
handoff_description="An english to italian translator",
58+
model=MODEL,
59+
)
5960

60-
# Orchestrator agent that uses other agents as tools
61-
# Uses output_type for structured outputs (native OpenAI Agents pattern)
62-
# Note: Using AgentOutputSchema with strict_json_schema=False because
63-
# dict[str, str] is not compatible with OpenAI's strict JSON schema mode
64-
orchestrator_agent = Agent(
65-
name="orchestrator_agent",
66-
instructions=(
67-
"You are a translation agent. You use the tools given to you to translate. "
68-
"If asked for multiple translations, you call the relevant tools in order. "
69-
"You never translate on your own, you always use the provided tools."
70-
),
71-
tools=[
72-
spanish_agent.as_tool(
73-
tool_name="translate_to_spanish",
74-
tool_description="Translate the user's message to Spanish",
75-
),
76-
french_agent.as_tool(
77-
tool_name="translate_to_french",
78-
tool_description="Translate the user's message to French",
61+
# Orchestrator agent that uses other agents as tools
62+
# Uses output_type for structured outputs (native OpenAI Agents pattern)
63+
# Note: Using AgentOutputSchema with strict_json_schema=False because
64+
# dict[str, str] is not compatible with OpenAI's strict JSON schema mode
65+
orchestrator_agent = Agent(
66+
name="orchestrator_agent",
67+
instructions=(
68+
"You are a translation agent. You use the tools given to you to translate. "
69+
"If asked for multiple translations, you call the relevant tools in order. "
70+
"You never translate on your own, you always use the provided tools."
7971
),
80-
italian_agent.as_tool(
81-
tool_name="translate_to_italian",
82-
tool_description="Translate the user's message to Italian",
83-
),
84-
],
85-
output_type=AgentOutputSchema(TranslationOutput, strict_json_schema=False),
86-
)
87-
88-
89-
@traced(name="Translation Orchestrator Main")
90-
async def main(input_data: TranslationInput) -> TranslationOutput:
91-
"""
92-
Main function to orchestrate translations using agent-as-tools pattern.
93-
94-
This function demonstrates parameter inference - the Input/Output models
95-
are automatically extracted to generate schemas for UiPath workflows.
96-
97-
Args:
98-
input_data: Input containing text and target languages
99-
100-
Returns:
101-
TranslationOutput: Result containing translations for requested languages
102-
"""
103-
print(f"\nTranslating: '{input_data.text}'")
104-
print(f"Target languages: {', '.join(input_data.target_languages)}\n")
105-
106-
# Build the prompt based on requested languages
107-
language_list = ", ".join(input_data.target_languages)
108-
prompt = f"Translate this text to {language_list}: {input_data.text}"
109-
110-
with trace("Translation Orchestrator"):
111-
# Run the orchestrator agent
112-
result = await Runner.run(
113-
starting_agent=orchestrator_agent,
114-
input=[{"content": prompt, "role": "user"}],
115-
)
116-
117-
# Extract translations from the response
118-
# In a real implementation, you'd parse the structured response
119-
final_response = result.final_output
120-
print(f"\nAgent response: {final_response}\n")
121-
122-
# For demonstration, create structured output
123-
# In production, you'd parse the agent's structured response
124-
translations = {}
125-
for lang in input_data.target_languages:
126-
# Placeholder - in real usage, extract from agent response
127-
translations[lang] = f"[Translation to {lang}]"
128-
129-
return TranslationOutput(
130-
original_text=input_data.text,
131-
translations=translations,
132-
languages_used=input_data.target_languages,
72+
tools=[
73+
spanish_agent.as_tool(
74+
tool_name="translate_to_spanish",
75+
tool_description="Translate the user's message to Spanish",
76+
),
77+
french_agent.as_tool(
78+
tool_name="translate_to_french",
79+
tool_description="Translate the user's message to French",
80+
),
81+
italian_agent.as_tool(
82+
tool_name="translate_to_italian",
83+
tool_description="Translate the user's message to Italian",
84+
),
85+
],
86+
output_type=AgentOutputSchema(TranslationOutput, strict_json_schema=False),
87+
model=MODEL,
13388
)
89+
90+
return orchestrator_agent
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"agents": {
3-
"agent": "main.py:orchestrator_agent"
3+
"agent": "main.py:main"
44
}
55
}

packages/uipath-openai-agents/samples/agent-as-tools/pyproject.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description = "Language routing agent example using OpenAI Agents"
55
readme = "README.md"
66
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath-openai-agents>=0.1.0, <0.2.0",
8+
"uipath-openai-agents>=0.0.1, <0.1.0",
99
"openai-agents>=0.6.5",
1010
"uipath>=2.4.10",
1111
]
@@ -14,6 +14,3 @@ dependencies = [
1414
dev = [
1515
"uipath-dev>=0.0.8",
1616
]
17-
18-
[tool.uv.sources]
19-
uipath-openai-agents = { path = "../..", editable = true }

packages/uipath-openai-agents/samples/agent-as-tools/uv.lock

Lines changed: 64 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)