Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,8 @@ cython_debug/

# PyPI configuration file
.pypirc

**/uipath.db
**/.uipath
**/**.nupkg
**/__uipath/
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uipath-llamaindex"
version = "0.0.4"
version = "0.0.5"
description = "UiPath LlamaIndex SDK"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.10"
Expand Down
2 changes: 1 addition & 1 deletion samples/quickstart-agent/llama_index.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": ["."],
"workflows": {
"agentic_w": "main.py:agent"
"agent": "main.py:agent"
},
"env": ".env"
}
6 changes: 5 additions & 1 deletion samples/quickstart-agent/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
from llama_index.llms.openai import OpenAI


class TopicEvent(StartEvent):
topic: str


class JokeEvent(Event):
joke: str

Expand All @@ -16,7 +20,7 @@ class JokeFlow(Workflow):
llm = OpenAI()

@step
async def generate_joke(self, ev: StartEvent) -> JokeEvent:
async def generate_joke(self, ev: TopicEvent) -> JokeEvent:
topic = ev.topic

prompt = f"Write your best joke about {topic}."
Expand Down
6 changes: 3 additions & 3 deletions samples/quickstart-agent/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "llama-demo"
version = "0.0.1"
description = "UiPath LlamaIndex SDK"
name = "llama-quickstart-agent"
version = "0.0.2"
description = "UiPath LlamaIndex Quickstart Agent"
authors = [{ name = "John Doe", email = "john.doe@myemail.com" }]
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.10"
Expand Down
30 changes: 30 additions & 0 deletions samples/quickstart-agent/uipath.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"entryPoints": [
{
"filePath": "agent",
"uniqueId": "f646d823-434c-4ef6-b8fb-6a239ee08974",
"type": "agent",
"input": {
"type": "object",
"properties": {
"topic": {
"title": "Topic",
"type": "string"
}
},
"required": [
"topic"
]
},
"output": {
"type": "object",
"properties": {},
"required": []
}
}
],
"bindings": {
"version": "2.0",
"resources": []
}
}
2,757 changes: 2,757 additions & 0 deletions samples/quickstart-agent/uv.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/uipath_llamaindex/_cli/_runtime/_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
from typing import Optional

from llama_index.core.workflow import StartEvent
from uipath import UiPath
from uipath._cli._runtime._contracts import (
UiPathBaseRuntime,
Expand Down Expand Up @@ -40,7 +39,9 @@ async def execute(self) -> Optional[UiPathRuntimeResult]:
await self.validate()

try:
ev = StartEvent(**self.context.input_json)
start_event_class = self.context.workflow._start_event_class

ev = start_event_class(**self.context.input_json)

handler = self.context.workflow.run(start_event=ev)

Expand Down
49 changes: 4 additions & 45 deletions src/uipath_llamaindex/_cli/cli_init.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import asyncio
import inspect
import json
import os
import uuid
from typing import Any, Dict, Optional, Type, get_type_hints
from typing import Any, Dict

from llama_index.core.workflow import Event, StartEvent, StopEvent, Workflow
from llama_index.core.workflow.decorators import StepConfig
from llama_index.core.workflow import StopEvent, Workflow
from uipath._cli._utils._console import ConsoleLogger
from uipath._cli._utils._parse_ast import generate_bindings_json # type: ignore
from uipath._cli.middlewares import MiddlewareResult
Expand Down Expand Up @@ -50,45 +48,6 @@ def process_nullable_types(properties: Dict[str, Any]) -> Dict[str, Any]:
return result


def find_event_types(workflow: Workflow, event_base_class: Type[Event]) -> Type[Event]:
"""Find the StartEvent or StopEvent class in a workflow"""
event_classes = set()

# Get all steps from the workflow
steps = {}

# Get steps defined as methods
for name, method in inspect.getmembers(workflow, inspect.ismethod):
if hasattr(method, "__step_config"):
steps[name] = method

# Get steps defined as free functions
class_steps = getattr(workflow.__class__, "_step_functions", {})
steps.update(class_steps)

# Find all event types that are subclasses of event_base_class
for step_func in steps.values():
step_config: Optional[StepConfig] = getattr(step_func, "__step_config")

if event_base_class is StartEvent:
# Look in accepted_events for StartEvent
for event_type in step_config.accepted_events:
if issubclass(event_type, event_base_class):
event_classes.add(event_type)
else:
# Look in return_types for StopEvent
for event_type in step_config.return_types:
if issubclass(event_type, event_base_class):
event_classes.add(event_type)

if len(event_classes) == 1:
return event_classes.pop()
elif len(event_classes) > 1:
# Return the most specific one (the one with the most fields)
return max(event_classes, key=lambda cls: len(get_type_hints(cls)))
return event_base_class # Default fallback


def generate_schema_from_workflow(workflow: Workflow) -> Dict[str, Any]:
"""Extract input/output schema from a LlamaIndex workflow"""
schema = {
Expand All @@ -97,8 +56,8 @@ def generate_schema_from_workflow(workflow: Workflow) -> Dict[str, Any]:
}

# Find the actual StartEvent and StopEvent classes used in this workflow
start_event_class = find_event_types(workflow, StartEvent)
stop_event_class = find_event_types(workflow, StopEvent)
start_event_class = workflow._start_event_class
stop_event_class = workflow._stop_event_class

# Generate input schema from StartEvent using Pydantic's schema method
try:
Expand Down