Repository: emcie-co/parlant
File: src/parlant/core/engines/alpha/tool_caller.py (Python)

Code before:

class ToolCallEvaluation(DefaultBaseModel):
    applicability_rationale: str
    applicability_score: Optional[int] = (
        None  # No longer used; left here as a reminder of the original design
    )
    is_applicable: bool
    argument_evaluations: Optional[list[ArgumentEvaluation]] = None
    same_call_is_already_staged: bool
    comparison_with_rejected_tools_including_references_to_subtleties: str
    relevant_subtleties: str
    a_rejected_tool_would_have_been_a_better_fit_if_it_werent_already_rejected: bool
    potentially_better_rejected_tool_name: Optional[str] = None
    potentially_better_rejected_tool_rationale: Optional[str] = None
    the_better_rejected_tool_should_clearly_be_run_in_tandem_with_the_candidate_tool: Optional[
        bool
    ] = None
    # These 3 ARQs are for cases we've observed where many optional arguments are missing
    # such that the model would be possibly biased to say the tool shouldn't run.
    are_optional_arguments_missing: bool
    are_non_optional_arguments_missing: bool
    allowed_to_run_without_optional_arguments_even_if_they_are_missing: bool
    should_run: Optional[bool] = (
        None  # No longer used; left here as a reminder of the original design
    )


class ToolCallInferenceSchema(DefaultBaseModel):
    last_customer_message: Optional[str] = None
    most_recent_customer_inquiry_or_need: Optional[str] = None
    most_recent_customer_inquiry_or_need_was_already_resolved: Optional[bool] = None
    name: str
    subtleties_to_be_aware_of: str
    tool_calls_for_candidate_tool: list[ToolCallEvaluation]


@dataclass
class ToolCallerInferenceShot(Shot):
    expected_result: ToolCallInferenceSchema


@dataclass(frozen=True)
class ToolCall:
    id: ToolCallId
    tool_id: ToolId
    arguments: Mapping[str, JSONSerializable]

    def __eq__(self, value: object) -> bool:
        if isinstance(value, ToolCall):
            return bool(self.tool_id == value.tool_id and self.arguments == value.arguments)
        return False

Review comment (performance):
@HadarYosef1 I think we can remove the optional `should_run` and `applicability_score`.

1. The reminders will stay there in the git history if we ever need to reference them
2. They might affect the constrained decoding aspect of structured outputs, potentially slowing down or reducing accuracy in completions.

Code after:

class ToolCallEvaluation(DefaultBaseModel):
    applicability_rationale: str
    is_applicable: bool
    argument_evaluations: Optional[list[ArgumentEvaluation]] = None
    same_call_is_already_staged: bool
    comparison_with_rejected_tools_including_references_to_subtleties: Optional[str] = None
    relevant_subtleties: str
    a_rejected_tool_would_have_been_a_better_fit_if_it_werent_already_rejected: Optional[bool] = (
        None
    )
    potentially_better_rejected_tool_name: Optional[str] = None
    potentially_better_rejected_tool_rationale: Optional[str] = None
    the_better_rejected_tool_should_clearly_be_run_in_tandem_with_the_candidate_tool: Optional[
        bool
    ] = None
    # These 3 ARQs are for cases we've observed where many optional arguments are missing
    # such that the model would be possibly biased to say the tool shouldn't run.
    are_optional_arguments_missing: Optional[bool] = None
    are_non_optional_arguments_missing: Optional[bool] = None
    allowed_to_run_without_optional_arguments_even_if_they_are_missing: Optional[bool] = None


class ToolCallInferenceSchema(DefaultBaseModel):
    last_customer_message: Optional[str] = None
    most_recent_customer_inquiry_or_need: Optional[str] = None
    most_recent_customer_inquiry_or_need_was_already_resolved: Optional[bool] = None
    name: str
    subtleties_to_be_aware_of: str
    tool_calls_for_candidate_tool: list[ToolCallEvaluation]


ToolCallFeature: TypeAlias = Literal["has_reference_tools", "has_optional_arguments"]


@dataclass
class ToolCallerInferenceShot(Shot):
    feature_set: list[ToolCallFeature]
    expected_result: ToolCallInferenceSchema


@dataclass(frozen=True)
class ToolCall:
    id: ToolCallId
    tool_id: ToolId
    arguments: Mapping[str, JSONSerializable]

    def __eq__(self, value: object) -> bool:
        if isinstance(value, ToolCall):
            return bool(self.tool_id == value.tool_id and self.arguments == value.arguments)
        return False