mirror of
https://github.com/Significant-Gravitas/AutoGPT-Code-Ability.git
synced 2026-11-09 23:51:28 -10:00
Integrating PyRight project-based code-linting. This will allow us to detect: * Misuse of async functions. * Misuse of optional type and other annotated types (currently disabled) * Wrong usage of pydantic and prisma model. * Wrong usage of third-party library. * Use of undeclared field * Use of uninstalled third-party library (which will prompt LLM to add the requirement list) Known trade-off: Setting-up PyRight requires building a full-project (generate the Prisma model code, installing 3rd-party library, compiling the function with the object dependency) this slows down the code-validation during the code-validation step. --------- Co-authored-by: majdyz <[email protected]> Co-authored-by: SwiftyOS <[email protected]>
130 lines
3.7 KiB
Python
130 lines
3.7 KiB
Python
"""
|
|
Function Helper Functions
|
|
"""
|
|
|
|
import logging
|
|
|
|
from prisma.enums import FunctionState
|
|
from prisma.models import CompiledRoute, ObjectType
|
|
from prisma.types import FunctionCreateInput, ObjectFieldCreateInput
|
|
|
|
from codex.common.model import (
|
|
FunctionDef,
|
|
ObjectTypeModel,
|
|
get_related_types,
|
|
normalize_type,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def construct_function(
|
|
function: FunctionDef, available_types: dict[str, ObjectType]
|
|
) -> FunctionCreateInput:
|
|
if not function.function_template:
|
|
raise ValueError("Function template is required")
|
|
|
|
input = FunctionCreateInput(
|
|
functionName=function.name,
|
|
template=function.function_template or "",
|
|
description=function.function_desc,
|
|
state=FunctionState.WRITTEN
|
|
if function.is_implemented
|
|
else FunctionState.DEFINITION,
|
|
rawCode=function.function_code,
|
|
functionCode=function.function_code,
|
|
)
|
|
|
|
if function.return_type:
|
|
field = ObjectFieldCreateInput(
|
|
name="return",
|
|
description=function.return_desc,
|
|
typeName=normalize_type(function.return_type),
|
|
RelatedTypes={
|
|
"connect": [
|
|
{"id": type.id}
|
|
for type in get_related_types(function.return_type, available_types)
|
|
]
|
|
},
|
|
)
|
|
input["FunctionReturn"] = {"create": field}
|
|
|
|
if function.arg_types:
|
|
fields = [
|
|
ObjectFieldCreateInput(
|
|
name=name,
|
|
description=function.arg_descs.get(name, "-"),
|
|
typeName=normalize_type(type),
|
|
RelatedTypes={
|
|
"connect": [
|
|
{"id": type.id}
|
|
for type in get_related_types(type, available_types)
|
|
]
|
|
},
|
|
)
|
|
for name, type in function.arg_types
|
|
]
|
|
input["FunctionArgs"] = {"create": fields} # type: ignore
|
|
|
|
return input
|
|
|
|
|
|
def generate_object_code(obj: ObjectTypeModel) -> str:
|
|
if not obj.name:
|
|
return "" # Avoid generating an empty object
|
|
|
|
# Auto-generate a template for the object, this will not capture any class functions.
|
|
fields = f"\n{' ' * 8}".join(
|
|
[
|
|
f"{field.name}: {field.type} "
|
|
f"{('= '+field.value) if field.value else ''} "
|
|
f"{('# '+field.description) if field.description else ''}"
|
|
for field in obj.Fields or []
|
|
]
|
|
)
|
|
|
|
parent_class = ""
|
|
if obj.is_enum:
|
|
parent_class = "Enum"
|
|
elif obj.is_pydantic:
|
|
parent_class = "BaseModel"
|
|
|
|
doc_string = (
|
|
f"""\"\"\"
|
|
{obj.description}
|
|
\"\"\""""
|
|
if obj.description
|
|
else ""
|
|
)
|
|
|
|
method_body = ("\n" + " " * 8).join(obj.code.split("\n")) + "\n" if obj.code else ""
|
|
|
|
template = f"""
|
|
class {obj.name}({parent_class}):
|
|
{doc_string if doc_string else ""}
|
|
{fields if fields else ""}
|
|
{method_body if method_body else ""}
|
|
{"pass" if not fields and not method_body else ""}
|
|
"""
|
|
return "\n".join([line[4:] for line in template.split("\n")]).strip()
|
|
|
|
|
|
def generate_object_template(obj: ObjectType) -> str:
|
|
return generate_object_code(ObjectTypeModel(db_obj=obj))
|
|
|
|
|
|
def get_database_schema(compiled_route: CompiledRoute) -> str:
|
|
return (
|
|
"\n\n".join(
|
|
[
|
|
t.definition
|
|
for t in compiled_route.ApiRouteSpec.DatabaseSchema.DatabaseTables
|
|
]
|
|
)
|
|
if compiled_route
|
|
and compiled_route.ApiRouteSpec
|
|
and compiled_route.ApiRouteSpec.DatabaseSchema
|
|
and compiled_route.ApiRouteSpec.DatabaseSchema.DatabaseTables
|
|
else ""
|
|
)
|