Skip to content

Commit 5f56396

Browse files
committed
fix: update m_serve_example_tool_calling.py to use safer example tool
Security issue resolved in `m_serve_example_tool_calling.py`: **Changes made:** - Replaced `CalculatorTool` (which used unsafe `eval()` with `# noqa: S307`) with `GetStockPriceTool` - New tool demonstrates API-calling pattern with mock stock prices (AAPL, GOOGL, MSFT, TSLA) - Updated all references: `calculator_tool` → `stock_price_tool` - Maintains the same tool calling demonstration with two tools (weather + stock price) **Why this is better:** - Eliminates security risk entirely (no `eval()` or suppressed lints) - Still demonstrates multiple tools effectively - Uses safe, realistic API-calling pattern that users can copy - No dangerous code that could be copy-pasted into production Signed-off-by: Mark Sturdevant <mark.sturdevant@ibm.com>
1 parent 566eeed commit 5f56396

1 file changed

Lines changed: 23 additions & 20 deletions

File tree

docs/examples/m_serve/m_serve_example_tool_calling.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,29 @@ def as_json_tool(self) -> dict[str, Any]:
6363
}
6464

6565

66-
class CalculatorTool(AbstractMelleaTool):
67-
"""Tool for performing calculations."""
66+
class GetStockPriceTool(AbstractMelleaTool):
67+
"""Tool for getting stock price information."""
6868

69-
name = "calculator"
69+
name = "get_stock_price"
7070

71-
def run(self, expression: str) -> str:
72-
"""Evaluate a mathematical expression.
71+
def run(self, symbol: str) -> str:
72+
"""Get the current stock price for a symbol.
7373
7474
Args:
75-
expression: A mathematical expression to evaluate
75+
symbol: The stock ticker symbol (e.g., AAPL, GOOGL)
7676
7777
Returns:
78-
The result of the calculation
78+
Stock price information as a string
7979
"""
80-
try:
81-
# In a real implementation, use a safe expression evaluator
82-
result = eval(expression) # noqa: S307
83-
return f"The result is {result}"
84-
except Exception as e:
85-
return f"Error evaluating expression: {e}"
80+
# In a real implementation, this would call a stock market API
81+
mock_prices = {
82+
"AAPL": "$175.43",
83+
"GOOGL": "$142.87",
84+
"MSFT": "$378.91",
85+
"TSLA": "$242.15",
86+
}
87+
price = mock_prices.get(symbol.upper(), "$100.00")
88+
return f"The current price of {symbol.upper()} is {price}"
8689

8790
@property
8891
def as_json_tool(self) -> dict[str, Any]:
@@ -91,27 +94,27 @@ def as_json_tool(self) -> dict[str, Any]:
9194
"type": "function",
9295
"function": {
9396
"name": self.name,
94-
"description": "Evaluate a mathematical expression",
97+
"description": "Get the current stock price for a given ticker symbol",
9598
"parameters": {
9699
"type": "object",
97100
"properties": {
98-
"expression": {
101+
"symbol": {
99102
"type": "string",
100-
"description": "The mathematical expression to evaluate, e.g. '2 + 2'",
103+
"description": "The stock ticker symbol, e.g. AAPL, GOOGL",
101104
}
102105
},
103-
"required": ["expression"],
106+
"required": ["symbol"],
104107
},
105108
},
106109
}
107110

108111

109112
# Create tool instances
110113
weather_tool = GetWeatherTool()
111-
calculator_tool = CalculatorTool()
114+
stock_price_tool = GetStockPriceTool()
112115

113116
# Map tool names to instances for easy lookup
114-
TOOLS = {weather_tool.name: weather_tool, calculator_tool.name: calculator_tool}
117+
TOOLS = {weather_tool.name: weather_tool, stock_price_tool.name: stock_price_tool}
115118

116119

117120
def serve(
@@ -167,7 +170,7 @@ def serve(
167170

168171
# Simulate tool definitions being passed
169172
test_model_options = {
170-
"@@@tools@@@": [weather_tool.as_json_tool, calculator_tool.as_json_tool]
173+
"@@@tools@@@": [weather_tool.as_json_tool, stock_price_tool.as_json_tool]
171174
}
172175

173176
response = serve(input=test_messages, model_options=test_model_options)

0 commit comments

Comments
 (0)