Skip to content

Conversation

@mike-deem-uipath
Copy link

@mike-deem-uipath mike-deem-uipath commented Jan 12, 2026

Depends on UiPath/uipath-runtime-python#65

Adds support for conversational agents:

  • Adds some optional overrides for local testing with CAS (configured using env vars)
  • Log conversation error events received from CAS over the websocket bridge
  • Adds an is_conversational getter to AgentDefinition
  • Adds --keep-state-file cli option that causes the state.db to be preserved. This allows conversational agent runs to accumulate conversation history.

Also

  • Fixed a minor typo in the autonomous agent system prompt.

@github-actions github-actions bot added test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-llamaindex Triggers tests in the uipath-llamaindex-python repository labels Jan 12, 2026
@mike-deem-uipath mike-deem-uipath force-pushed the feat/conv-agent-support branch 2 times, most recently from 08ce88b to 6843216 Compare January 13, 2026 00:33
@mike-deem-uipath mike-deem-uipath marked this pull request as ready for review January 13, 2026 00:39
@mike-deem-uipath mike-deem-uipath force-pushed the feat/conv-agent-support branch 3 times, most recently from 049870f to 464caaa Compare January 14, 2026 01:42
"--keep-state-file",
is_flag=True,
help="Keep the state file even when not resuming and no job id is provided",
)
Copy link
Member

@cristipufu cristipufu Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's replace this with:

@click.option(
    "--state-file",
    required=False,
    type=click.Path(exists=True),
    help="Full path to the state file (takes priority over default location)"
)

Trying to shoot two birds with one stone, if we have this specified, we just use it as an override and don't delete it. Updated the runtime PR as well https://github.com/UiPath/uipath-runtime-python/pull/65/changes

We need to update the pyproject.toml with the new runtime version range + increment the minor here as well

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now if I want to keep the file, I have to know and provide the path to it? This doesn't make sense to me... the file you want to use and if you want to keep it are separate concepts.

Copy link
Author

@mike-deem-uipath mike-deem-uipath Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where the keep-state-file flag was used: https://github.com/UiPath/uipath-langchain-python/pull/395/changes#diff-7533e122e0f409dfcb61aa90e55e348bb528eac57d711599e88b198f38a467adR70. So this becomes self.context.state_file_path is not None. Why would one expect just setting that property to have the side effect of not deleting the file? And what if I want the file to be deleted AND I want to override the path?

Having an explicit keep-state-file flag avoids these unexpected side effects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the state file pointer for something else, was thinking we can re-use the concept for this as well, and avoid adding another option.

If you insist, you can add the keep-state-file option back

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea behind my thoughts is that you either:

  • provide your own sqlite database, which we use to store the state
  • or we create a temporary one for the local run and clean-up afterwards

resume=resume,
command="run",
trace_manager=trace_manager,
keep_state_file=keep_state_file,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state_file_path=state_file


def generate_conversational_agent_system_prompt(
agent_definition: LowCodeAgentDefinition,
user_settings: Optional[PromptUserSettings],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's change this method's signature to only use what it needs from LowCodeAgentDefinition (agent_name str, model str, system_message). we need to re-use it for the conversion flow

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for reference, this is how a converted autonomous low-code agent looks today:

class AgentInput(BaseModel):
    pass

class AgentOutput(BaseModel):
    content: str | None = Field(None, description="Output content")

# Agent Messages Function
def create_messages(state: AgentInput) -> Sequence[SystemMessage | HumanMessage]:
    # Apply system prompt template
    current_date = datetime.now(timezone.utc).strftime('%Y-%m-%d')
    system_prompt_content = f"""You are an agentic assistant."""
    enhanced_system_prompt = (
        AGENT_SYSTEM_PROMPT_TEMPLATE
        .replace('{{systemPrompt}}', system_prompt_content)
        .replace('{{currentDate}}', current_date)
        .replace('{{agentName}}', 'Mr Assistant')
    )

    return [
        SystemMessage(content=enhanced_system_prompt),
        HumanMessage(content=f"""What is the current date?"""),
    ]

# Create agent graph
graph = create_agent(model=llm, messages=create_messages, tools=all_tools, input_schema=AgentInput, output_schema=AgentOutput)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also rename the method to get_chat_system_prompt to be consistent with current public namespaces

import os
import uuid
from typing import Any
from typing import Any, Dict
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use buit-in types (dict not Dict, x | None instead of Optional etc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-llamaindex Triggers tests in the uipath-llamaindex-python repository

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants