Skip to content

Commit 287d4b7

Browse files
committed
feedback
Signed-off-by: Filinto Duran <[email protected]>
1 parent 08fdcab commit 287d4b7

File tree

4 files changed

+5
-180
lines changed

4 files changed

+5
-180
lines changed

dapr/aio/clients/grpc/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,14 +1763,14 @@ async def converse_alpha1(
17631763
for inp in inputs
17641764
]
17651765

1766-
# # Convert raw Python parameters to GrpcAny objects
1767-
# converted_parameters = convert_parameters(parameters)
1766+
# Convert raw Python parameters to GrpcAny objects
1767+
converted_parameters = convert_dict_to_grpc_dict_of_any(parameters)
17681768

17691769
request = api_v1.ConversationRequest(
17701770
name=name,
17711771
inputs=inputs_pb,
17721772
contextID=context_id,
1773-
parameters=parameters,
1773+
parameters=converted_parameters,
17741774
metadata=metadata or {},
17751775
scrubPII=scrub_pii,
17761776
temperature=temperature,
File renamed without changes.

dapr/clients/grpc/_helpers.py

Lines changed: 1 addition & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
BytesValue,
3030
)
3131
from google.protobuf.struct_pb2 import Struct
32+
from google.protobuf import json_format
3233

3334
MetadataDict = Dict[str, List[Union[bytes, str]]]
3435
MetadataTuple = Tuple[Tuple[str, Union[bytes, str]], ...]
@@ -149,8 +150,6 @@ def convert_value_to_struct(value: Dict[str, Any]) -> Struct:
149150
if not isinstance(value, dict) and not isinstance(value, bytes):
150151
raise ValueError(f'Value must be a dictionary, got {type(value)}')
151152

152-
from google.protobuf import json_format
153-
154153
# Convert the value to a JSON-serializable format first
155154
# Handle bytes by converting to base64 string for JSON compatibility
156155
if isinstance(value, bytes):
@@ -241,170 +240,3 @@ def convert_dict_to_grpc_dict_of_any(parameters: Optional[Dict[str, Any]]) -> Di
241240
converted[key] = convert_value_to_grpc_any(value)
242241

243242
return converted
244-
245-
246-
def create_tool_function(
247-
name: str,
248-
description: str,
249-
parameters: Optional[Dict[str, Any]] = None,
250-
required: Optional[List[str]] = None,
251-
) -> 'ConversationToolsFunction':
252-
"""Create a tool function with automatic parameter conversion.
253-
254-
This helper automatically converts Python dictionaries to the proper JSON Schema
255-
format required by the Dapr Conversation API.
256-
257-
The parameters map directly represents the JSON schema structure using proper protobuf types.
258-
259-
Args:
260-
name: Function name
261-
description: Human-readable description of what the function does
262-
parameters: Parameter definitions (raw Python dict)
263-
required: List of required parameter names
264-
265-
Returns:
266-
ConversationToolsFunction ready to use with Alpha2 API
267-
268-
Examples:
269-
# Simple approach - properties become JSON schema
270-
>>> create_tool_function(
271-
... name="get_weather",
272-
... description="Get current weather",
273-
... parameters={
274-
... "location": {"type": "string", "description": "City name"},
275-
... "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
276-
... },
277-
... required=["location"]
278-
... )
279-
# Creates: parameters = {
280-
# "type": StringValue("object"),
281-
# "properties": Struct({...}),
282-
# "required": ListValue([...])
283-
# }
284-
285-
# Full JSON Schema approach (already complete)
286-
>>> create_tool_function(
287-
... name="calculate",
288-
... description="Perform calculations",
289-
... parameters={
290-
... "type": "object",
291-
... "properties": {
292-
... "expression": {"type": "string", "description": "Math expression"}
293-
... },
294-
... "required": ["expression"]
295-
... }
296-
... )
297-
# Maps schema fields directly to protobuf map
298-
299-
# No parameters
300-
>>> create_tool_function(
301-
... name="get_time",
302-
... description="Get current time"
303-
... )
304-
# Creates: parameters = {}
305-
"""
306-
from dapr.clients.grpc._request import ConversationToolsFunction
307-
308-
if parameters is None:
309-
# No parameters - simple case
310-
return ConversationToolsFunction(name=name, description=description, parameters={})
311-
312-
# Build the complete JSON Schema object
313-
if isinstance(parameters, dict):
314-
# Check if it's already a complete JSON schema
315-
if 'type' in parameters and parameters['type'] == 'object':
316-
# Complete JSON schema provided - use as-is
317-
json_schema = parameters.copy()
318-
# Add required field if provided separately and not already present
319-
if required and 'required' not in json_schema:
320-
json_schema['required'] = required
321-
elif 'properties' in parameters:
322-
# Properties provided directly - wrap in JSON schema
323-
json_schema = {'type': 'object', 'properties': parameters['properties']}
324-
if required:
325-
json_schema['required'] = required
326-
elif 'required' in parameters:
327-
json_schema['required'] = parameters['required']
328-
else:
329-
# Assume it's a direct mapping of parameter names to schemas
330-
json_schema = {'type': 'object', 'properties': parameters}
331-
if required:
332-
json_schema['required'] = required
333-
else:
334-
raise ValueError(f'Parameters must be a dictionary, got {type(parameters)}')
335-
336-
# Map JSON schema fields directly to protobuf map entries
337-
# The parameters map directly represents the JSON schema structure
338-
converted_params = {}
339-
if json_schema:
340-
for key, value in json_schema.items():
341-
converted_params[key] = convert_value_to_struct(value)
342-
343-
return ConversationToolsFunction(
344-
name=name, description=description, parameters=converted_params
345-
)
346-
347-
348-
def create_tool(
349-
name: str,
350-
description: str,
351-
parameters: Optional[Dict[str, Any]] = None,
352-
required: Optional[List[str]] = None,
353-
) -> 'ConversationTools':
354-
"""Create a complete tool with automatic parameter conversion.
355-
356-
Args:
357-
name: Function name
358-
description: Human-readable description of what the function does
359-
parameters: JSON schema for function parameters (raw Python dict)
360-
required: List of required parameter names
361-
362-
Returns:
363-
ConversationTools ready to use with converse_alpha2()
364-
365-
Examples:
366-
# Weather tool
367-
>>> weather_tool = create_tool(
368-
... name="get_weather",
369-
... description="Get current weather for a location",
370-
... parameters={
371-
... "location": {
372-
... "type": "string",
373-
... "description": "The city and state or country"
374-
... },
375-
... "unit": {
376-
... "type": "string",
377-
... "enum": ["celsius", "fahrenheit"],
378-
... "description": "Temperature unit"
379-
... }
380-
... },
381-
... required=["location"]
382-
... )
383-
384-
# Calculator tool with full schema
385-
>>> calc_tool = create_tool(
386-
... name="calculate",
387-
... description="Perform mathematical calculations",
388-
... parameters={
389-
... "type": "object",
390-
... "properties": {
391-
... "expression": {
392-
... "type": "string",
393-
... "description": "Mathematical expression to evaluate"
394-
... }
395-
... },
396-
... "required": ["expression"]
397-
... }
398-
... )
399-
400-
# Simple tool with no parameters
401-
>>> time_tool = create_tool(
402-
... name="get_current_time",
403-
... description="Get the current date and time"
404-
... )
405-
"""
406-
from dapr.clients.grpc._request import ConversationTools
407-
408-
function = create_tool_function(name, description, parameters, required)
409-
410-
return ConversationTools(function=function)

pyproject.toml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@
22
target-version = "py38"
33
line-length = 100
44
fix = true
5-
extend-exclude = [
6-
".github",
7-
"dapr/proto",
8-
"tools/dapr/proto",
9-
"**/*_pb2.py",
10-
"**/*_pb2_grpc.py",
11-
"**/*_pb2.pyi"
12-
]
5+
extend-exclude = [".github", "dapr/proto"]
136
[tool.ruff.lint]
147
select = [
158
"E", # pycodestyle errors

0 commit comments

Comments
 (0)