Skip to content

Commit 554ec6b

Browse files
committed
feat(tests): added 2 integration tests
1 parent e6fc7fd commit 554ec6b

22 files changed

Lines changed: 6430 additions & 0 deletions
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Integration testing
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
integration-tests:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
pull-requests: write
15+
16+
strategy:
17+
matrix:
18+
include:
19+
- build-dir: quickstart-agent
20+
- build-dir: simple-hitl-agent
21+
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Docker Buildx
27+
uses: docker/setup-buildx-action@v3
28+
29+
- name: Build Docker image (${{ matrix.build-dir }})
30+
run: |
31+
docker build -f testcases/${{ matrix.build-dir }}/Dockerfile \
32+
-t ${{ matrix.build-dir }}:test \
33+
--build-arg CLIENT_ID="${{ secrets.ALPHA_TEST_CLIENT_ID }}" \
34+
--build-arg CLIENT_SECRET="${{ secrets.ALPHA_TEST_CLIENT_SECRET }}" \
35+
--build-arg BASE_URL="${{ secrets.ALPHA_BASE_URL }}" \
36+
.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
UIPATH_URL=xxx
2+
UIPATH_TENANT_ID=xxx
3+
UIPATH_ORGANIZATION_ID=xxx
4+
UIPATH_ACCESS_TOKEN=xxx
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
FROM ghcr.io/astral-sh/uv:python3.12-bookworm
2+
3+
WORKDIR /app
4+
5+
COPY . .
6+
7+
WORKDIR /app/testcases/quickstart-agent
8+
9+
RUN uv sync
10+
11+
ARG CLIENT_ID
12+
ARG CLIENT_SECRET
13+
ARG BASE_URL
14+
15+
RUN if [ -z "$CLIENT_ID" ]; then echo "CLIENT_ID build arg is required" && exit 1; fi
16+
RUN if [ -z "$CLIENT_SECRET" ]; then echo "CLIENT_SECRET build arg is required" && exit 1; fi
17+
RUN if [ -z "$BASE_URL" ]; then echo "BASE_URL build arg is required" && exit 1; fi
18+
19+
# Set environment variables for runtime
20+
ENV CLIENT_ID=$CLIENT_ID
21+
ENV CLIENT_SECRET=$CLIENT_SECRET
22+
ENV BASE_URL=$BASE_URL
23+
ENV TAVILY_API_KEY=${TAVILY_API_KEY:-""}
24+
ENV UIPATH_TENANT_ID=${UIPATH_TENANT_ID:-""}
25+
ENV UIPATH_JOB_KEY=8c6a342e-036e-492c-a3d2-99e66f6554ce
26+
27+
# Authenticate with UiPath during build
28+
RUN uv run uipath auth --client-id="$CLIENT_ID" --client-secret="$CLIENT_SECRET" --base-url="$BASE_URL"
29+
30+
RUN uv run uipath pack
31+
32+
RUN AGENT_INPUT=$(cat input.json) && uv run uipath run agent "$AGENT_INPUT"
33+
34+
# Run the Python assert script to validate output
35+
RUN python src/assert.py
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
flowchart TD
2+
step__done["_done"]:::stepStyle
3+
step_critique_joke["critique_joke"]:::stepStyle
4+
step_generate_joke["generate_joke"]:::stepStyle
5+
event_JokeEvent([<p>JokeEvent</p>]):::defaultEventStyle
6+
event_CritiqueEvent([<p>CritiqueEvent</p>]):::stopEventStyle
7+
event_TopicEvent([<p>TopicEvent</p>]):::defaultEventStyle
8+
event_CritiqueEvent --> step__done
9+
step_critique_joke --> event_CritiqueEvent
10+
event_JokeEvent --> step_critique_joke
11+
step_generate_joke --> event_JokeEvent
12+
event_TopicEvent --> step_generate_joke
13+
classDef stepStyle fill:#f2f0ff,line-height:1.2
14+
classDef externalStyle fill:#f2f0ff,line-height:1.2
15+
classDef defaultEventStyle fill-opacity:0
16+
classDef stopEventStyle fill:#bfb6fc
17+
classDef inputRequiredStyle fill:#f2f0ff,line-height:1.2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"topic": "cats"}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"dependencies": ["."],
3+
"workflows": {
4+
"agent": "./src/main.py:agent"
5+
},
6+
"env": ".env"
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[project]
2+
name = "llama-quickstart-agent"
3+
version = "0.0.6"
4+
description = "UiPath LlamaIndex Quickstart Agent"
5+
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]
6+
readme = { file = "README.md", content-type = "text/markdown" }
7+
requires-python = ">=3.10"
8+
dependencies = [
9+
"uipath-llamaindex",
10+
"llama-index-llms-openai>=0.2.2",
11+
"uipath>=2.0.82",
12+
]
13+
14+
[tool.uv.sources]
15+
uipath-llamaindex = { path = "../../", editable = true }
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import os
2+
import sys
3+
import json
4+
5+
print("Checking quickstart agent output...")
6+
7+
# Check NuGet package
8+
uipath_dir = ".uipath"
9+
if not os.path.exists(uipath_dir):
10+
print("NuGet package directory (.uipath) not found")
11+
sys.exit(1)
12+
13+
nupkg_files = [f for f in os.listdir(uipath_dir) if f.endswith('.nupkg')]
14+
if not nupkg_files:
15+
print("NuGet package file (.nupkg) not found in .uipath directory")
16+
sys.exit(1)
17+
18+
print(f"NuGet package found: {nupkg_files[0]}")
19+
20+
# Check agent output file
21+
output_file = "__uipath/output.json"
22+
if not os.path.isfile(output_file):
23+
print("Agent output file not found")
24+
sys.exit(1)
25+
26+
print("Agent output file found")
27+
28+
# Check status and required fields
29+
try:
30+
with open(output_file, 'r', encoding='utf-8') as f:
31+
output_data = json.load(f)
32+
33+
# Check status
34+
status = output_data.get("status")
35+
if status != "successful":
36+
print(f"Agent execution failed with status: {status}")
37+
sys.exit(1)
38+
39+
print("Agent execution status: successful")
40+
41+
# Check required fields for quickstart agent
42+
if "output" not in output_data:
43+
print("Missing 'output' field in agent response")
44+
sys.exit(1)
45+
46+
output_content = output_data["output"]
47+
if "joke" not in output_content:
48+
print("Missing 'joke' field in output")
49+
sys.exit(1)
50+
51+
joke = output_content["joke"]
52+
if not joke or joke.strip() == "":
53+
print("Joke field is empty")
54+
sys.exit(1)
55+
56+
if "critique" not in output_content:
57+
print("Missing 'critique' field in output")
58+
sys.exit(1)
59+
60+
critique = output_content["critique"]
61+
if not critique or critique.strip() == "":
62+
print("Critique field is empty")
63+
sys.exit(1)
64+
65+
print(f"Joke: {joke}")
66+
print(f"Critique: {critique}")
67+
68+
print("Required fields validation passed")
69+
print("Quickstart agent working correctly.")
70+
71+
except Exception as e:
72+
print(f"Error checking output: {e}")
73+
sys.exit(1)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from llama_index.core.workflow import (
2+
Event,
3+
StartEvent,
4+
StopEvent,
5+
Workflow,
6+
step,
7+
)
8+
9+
from uipath_llamaindex.llms import UiPathOpenAI
10+
11+
class TopicEvent(StartEvent):
12+
topic: str
13+
14+
15+
class JokeEvent(Event):
16+
joke: str
17+
18+
19+
class CritiqueEvent(StopEvent):
20+
joke: str
21+
critique: str
22+
23+
24+
class JokeFlow(Workflow):
25+
llm = UiPathOpenAI(model="gpt-4o-mini-2024-07-18")
26+
27+
@step
28+
async def generate_joke(self, ev: TopicEvent) -> JokeEvent:
29+
topic = ev.topic
30+
31+
prompt = f"Write your best joke about {topic}."
32+
response = await self.llm.acomplete(prompt)
33+
return JokeEvent(joke=str(response))
34+
35+
@step
36+
async def critique_joke(self, ev: JokeEvent) -> CritiqueEvent:
37+
joke = ev.joke
38+
39+
prompt = f"Give a thorough analysis and critique of the following joke: {joke}"
40+
response = await self.llm.acomplete(prompt)
41+
return CritiqueEvent(joke=joke, critique=str(response))
42+
43+
44+
agent = JokeFlow(timeout=60, verbose=False)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"entryPoints": [
3+
{
4+
"filePath": "agent",
5+
"uniqueId": "a1ac234f-75bc-4f3a-9bae-514f53cd86db",
6+
"type": "agent",
7+
"input": {
8+
"type": "object",
9+
"properties": {
10+
"topic": {
11+
"title": "Topic",
12+
"type": "string"
13+
}
14+
},
15+
"required": [
16+
"topic"
17+
]
18+
},
19+
"output": {
20+
"type": "object",
21+
"properties": {
22+
"joke": {
23+
"title": "Joke",
24+
"type": "string"
25+
},
26+
"critique": {
27+
"title": "Critique",
28+
"type": "string"
29+
}
30+
},
31+
"required": [
32+
"joke",
33+
"critique"
34+
]
35+
}
36+
}
37+
],
38+
"bindings": {
39+
"version": "2.0",
40+
"resources": []
41+
}
42+
}

0 commit comments

Comments
 (0)