Coverage for src/ollamapy/parameter_utils.py: 34%
56 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-01 12:29 -0400
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-01 12:29 -0400
1"""Shared utilities for parameter handling and conversion."""
3import re
4from typing import Any, Dict, Union
7def convert_parameter_value(value: Any, param_type: str) -> Any:
8 """Convert a parameter value to the expected type.
10 Args:
11 value: The value to convert
12 param_type: The expected type ('number' or 'string')
14 Returns:
15 The converted value, or the original value if conversion fails
16 """
17 if param_type == "number" and value is not None:
18 try:
19 # Try to convert to number
20 if isinstance(value, str):
21 # Remove any whitespace
22 value = value.strip()
23 # Handle both int and float
24 value = float(value)
25 # Convert to int if it's a whole number
26 if value.is_integer():
27 value = int(value)
28 except (ValueError, AttributeError):
29 # Return None to indicate conversion failure
30 return None
32 return value
35def validate_required_parameters(
36 parameters: Dict[str, Any], expected_params: Dict[str, Dict[str, Any]]
37) -> bool:
38 """Validate that all required parameters are present.
40 Args:
41 parameters: The actual parameters provided
42 expected_params: The expected parameter specifications
44 Returns:
45 True if all required parameters are present, False otherwise
46 """
47 for param_name, param_spec in expected_params.items():
48 if param_spec.get("required", False) and param_name not in parameters:
49 return False
50 return True
53def extract_numbers_from_text(text: str) -> list:
54 """Extract numbers from text using regex.
56 Args:
57 text: The text to extract numbers from
59 Returns:
60 List of numbers found in the text
61 """
62 numbers = re.findall(r"-?\d+\.?\d*", text)
63 result = []
64 for num_str in numbers:
65 try:
66 value = float(num_str)
67 result.append(int(value) if value.is_integer() else value)
68 except ValueError:
69 continue
70 return result
73def extract_expressions_from_text(text: str) -> list:
74 """Extract mathematical expressions from text.
76 Args:
77 text: The text to extract expressions from
79 Returns:
80 List of mathematical expressions found
81 """
82 # Simple pattern for basic arithmetic
83 expressions = re.findall(r"(\d+\s*[+\-*/]\s*\d+)", text)
84 return [expr.replace(" ", "") for expr in expressions]
87def prepare_function_parameters(
88 parameters: Dict[str, Any], expected_params: Dict[str, Dict[str, Any]]
89) -> Dict[str, Any]:
90 """Prepare parameters for function call by converting types and validating.
92 Args:
93 parameters: The raw parameters
94 expected_params: The expected parameter specifications
96 Returns:
97 Dictionary of prepared parameters ready for function call
98 """
99 call_params = {}
101 for param_name, param_spec in expected_params.items():
102 if param_name in parameters:
103 value = parameters[param_name]
105 # Type conversion
106 converted_value = convert_parameter_value(value, param_spec["type"])
107 if converted_value is None and param_spec["type"] == "number":
108 # Conversion failed for required number
109 raise ValueError(
110 f"Parameter '{param_name}' must be a number, got '{value}'"
111 )
113 call_params[param_name] = converted_value
114 elif param_spec.get("required", False):
115 raise ValueError(f"Required parameter '{param_name}' not provided")
117 return call_params
120def extract_parameter_from_response(response_content: str, param_type: str) -> Any:
121 """Extract parameter value from AI response content.
123 Args:
124 response_content: The cleaned response from AI
125 param_type: The expected parameter type
127 Returns:
128 The extracted parameter value, or None if not found
129 """
130 # Check if not found
131 if "NOT_FOUND" in response_content.upper() or not response_content:
132 return None
134 # Process based on type
135 if param_type == "number":
136 # Try to extract a number from the response
137 # First try to convert the whole response
138 try:
139 value = float(response_content)
140 return int(value) if value.is_integer() else value
141 except:
142 # Try to find a number in the response
143 numbers = extract_numbers_from_text(response_content)
144 if numbers:
145 return numbers[0]
146 return None
147 else:
148 # For string type, return the cleaned response
149 return response_content