Merge branch 'main' into matt/let-671-for-local-sandbox-using-local-env-variables-instead-of

This commit is contained in:
Charles Packer
2024-12-30 22:36:24 +01:00
committed by GitHub
2 changed files with 38 additions and 51 deletions

View File

@@ -396,44 +396,6 @@ def generate_schema(function, name: Optional[str] = None, description: Optional[
return schema
def generate_schema_from_args_schema_v1(
args_schema: Type[V1BaseModel], name: Optional[str] = None, description: Optional[str] = None, append_heartbeat: bool = True
) -> Dict[str, Any]:
properties = {}
required = []
for field_name, field in args_schema.__fields__.items():
if field.type_ == str:
field_type = "string"
elif field.type_ == int:
field_type = "integer"
elif field.type_ == bool:
field_type = "boolean"
else:
field_type = field.type_.__name__
properties[field_name] = {
"type": field_type,
"description": field.field_info.description,
}
if field.required:
required.append(field_name)
function_call_json = {
"name": name,
"description": description,
"parameters": {"type": "object", "properties": properties, "required": required},
}
if append_heartbeat:
function_call_json["parameters"]["properties"]["request_heartbeat"] = {
"type": "boolean",
"description": "Request an immediate heartbeat after function execution. Set to `True` if you want to send a follow-up message or run a follow-up function.",
}
function_call_json["parameters"]["required"].append("request_heartbeat")
return function_call_json
def generate_schema_from_args_schema_v2(
args_schema: Type[BaseModel], name: Optional[str] = None, description: Optional[str] = None, append_heartbeat: bool = True
) -> Dict[str, Any]:
@@ -441,19 +403,8 @@ def generate_schema_from_args_schema_v2(
required = []
for field_name, field in args_schema.model_fields.items():
field_type_annotation = field.annotation
if field_type_annotation == str:
field_type = "string"
elif field_type_annotation == int:
field_type = "integer"
elif field_type_annotation == bool:
field_type = "boolean"
else:
field_type = field_type_annotation.__name__
properties[field_name] = {
"type": field_type,
"description": field.description,
}
properties[field_name] = type_to_json_schema_type(field_type_annotation)
properties[field_name]["description"] = field.description
if field.is_required():
required.append(field_name)

View File

@@ -5,6 +5,7 @@ import pytest
from letta.functions.functions import derive_openai_json_schema
from letta.llm_api.helpers import convert_to_structured_output, make_post_request
from letta.schemas.tool import ToolCreate
def _clean_diff(d1, d2):
@@ -176,3 +177,38 @@ def test_valid_schemas_via_openai(openai_model: str, structured_output: bool):
_openai_payload(openai_model, schema, structured_output)
else:
_openai_payload(openai_model, schema, structured_output)
@pytest.mark.parametrize("openai_model", ["gpt-4o-mini"])
@pytest.mark.parametrize("structured_output", [True])
def test_composio_tool_schema_generation(openai_model: str, structured_output: bool):
"""Test that we can generate the schemas for some Composio tools."""
if not os.getenv("COMPOSIO_API_KEY"):
pytest.skip("COMPOSIO_API_KEY not set")
try:
import composio
except ImportError:
pytest.skip("Composio not installed")
for action_name in [
"CAL_GET_AVAILABLE_SLOTS_INFO", # has an array arg, needs to be converted properly
]:
try:
tool_create = ToolCreate.from_composio(action_name=action_name)
except composio.exceptions.ComposioSDKError:
# e.g. "composio.exceptions.ComposioSDKError: No connected account found for app `CAL`; Run `composio add cal` to fix this"
pytest.skip(f"Composio account not configured to use action_name {action_name}")
print(tool_create)
assert tool_create.json_schema
schema = tool_create.json_schema
try:
_openai_payload(openai_model, schema, structured_output)
print(f"Successfully called OpenAI using schema {schema} generated from {action_name}")
except:
print(f"Failed to call OpenAI using schema {schema} generated from {action_name}")
raise