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
6 changes: 6 additions & 0 deletions packages/uipath/src/uipath/agent/react/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@
from .conversational_prompts import (
PromptUserSettings,
get_chat_system_prompt,
get_generate_output_prompt,
)
from .conversational_voice_prompts import get_voice_system_prompt
from .prompts import AGENT_SYSTEM_PROMPT_TEMPLATE
from .tools import (
END_EXECUTION_TOOL,
RAISE_ERROR_TOOL,
SET_CONVERSATIONAL_OUTPUT_TOOL,
EndExecutionToolSchemaModel,
FlowControlToolConfig,
RaiseErrorToolSchemaModel,
SetConversationalOutputToolSchemaModel,
)

__all__ = [
"AGENT_SYSTEM_PROMPT_TEMPLATE",
"FlowControlToolConfig",
"END_EXECUTION_TOOL",
"RAISE_ERROR_TOOL",
"SET_CONVERSATIONAL_OUTPUT_TOOL",
"EndExecutionToolSchemaModel",
"RaiseErrorToolSchemaModel",
"SetConversationalOutputToolSchemaModel",
"PromptUserSettings",
"get_chat_system_prompt",
"get_generate_output_prompt",
"get_voice_system_prompt",
]
18 changes: 18 additions & 0 deletions packages/uipath/src/uipath/agent/react/conversational_prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,21 @@ def get_conversation_id_template(conversation_id: str | None) -> str:
if not conversation_id:
return ""
return _CONVERSATION_ID_TEMPLATE.format(conversation_id=conversation_id)


_GENERATE_OUTPUT_INSTRUCTION = """The conversational response for this turn has already been delivered to the user. Call the `set_conversational_output` tool to record the structured output fields for this turn.

Rules:
- For each field, use values inferred from the conversation's recent turn.
- For optional fields that are not yet relevant or determinable from the conversation so far, omit them entirely.
- For required fields that cannot yet be determined (e.g., the conversation is still gathering context, or the topic hasn't surfaced yet), use a clear placeholder value (e.g. "N/A" or "unknown" for string fields). DO NOT fabricate, guess, or hallucinate values.
- Do not produce any text content — only call the tool."""
Comment on lines +238 to +244


def get_generate_output_prompt() -> str:
"""Return the framework-internal generate-output instruction.

Appended as a final user-message to the conversational structured-output
node's LLM call.
"""
return _GENERATE_OUTPUT_INSTRUCTION
23 changes: 23 additions & 0 deletions packages/uipath/src/uipath/agent/react/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class FlowControlToolName(str, Enum):

END_EXECUTION = "end_execution"
RAISE_ERROR = "raise_error"
SET_CONVERSATIONAL_OUTPUT = "set_conversational_output"


@dataclass(frozen=True)
Expand Down Expand Up @@ -72,3 +73,25 @@ class RaiseErrorToolSchemaModel(BaseModel):
description="Raises an error and ends the execution of the agent",
args_schema=RaiseErrorToolSchemaModel,
)


class SetConversationalOutputToolSchemaModel(BaseModel):
"""Placeholder args_schema for the `set_conversational_output` tool.

Always overridden at construction time with the agent's stripped output
schema (i.e. the user's `outputSchema` with `uipath__agent_response_messages`
removed). Declared here so the tool entry has a well-typed default.
"""

model_config = ConfigDict(extra="forbid")

Comment on lines +78 to +87

SET_CONVERSATIONAL_OUTPUT_TOOL = FlowControlToolConfig(
name=FlowControlToolName.SET_CONVERSATIONAL_OUTPUT,
description=(
"Sets the structured output fields for the current conversational "
"turn. Called once per turn after the conversational response has been "
"delivered, to populate fields as the agent's output."
),
args_schema=SetConversationalOutputToolSchemaModel,
)
31 changes: 31 additions & 0 deletions packages/uipath/tests/agent/react/test_conversational_prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from uipath.agent.react.conversational_prompts import (
PromptUserSettings,
get_chat_system_prompt,
get_generate_output_prompt,
get_user_settings_template,
)

Expand Down Expand Up @@ -348,3 +349,33 @@ def test_full_settings_json_format(self):
assert json_data["company"] == "Big Corp"
assert json_data["country"] == "UK"
assert json_data["timezone"] == "Europe/London"


class TestGetGenerateOutputInstruction:
"""Tests for get_generate_output_prompt function."""

Comment on lines +354 to +356
def test_returns_non_empty_string(self):
instruction = get_generate_output_prompt()
assert isinstance(instruction, str)
assert instruction.strip()

def test_references_set_conversational_output_tool(self):
"""The instruction must name the tool the new node binds."""
assert "set_conversational_output" in get_generate_output_prompt()

def test_mentions_placeholder_rule_for_required_fields(self):
"""The instruction must steer the model toward 'N/A'-style placeholders
rather than fabricated values for required fields with no context yet."""
instruction = get_generate_output_prompt()
assert "N/A" in instruction or "unknown" in instruction.lower()

def test_mentions_omit_rule_for_optional_fields(self):
"""The instruction must steer the model toward omitting optional fields
when they're not yet relevant."""
instruction = get_generate_output_prompt().lower()
assert "omit" in instruction or "optional" in instruction

def test_no_text_content_directive(self):
"""The instruction must explicitly forbid producing conversational text."""
instruction = get_generate_output_prompt().lower()
assert "do not produce" in instruction or "only call the tool" in instruction
Loading