mirror of
https://github.com/Significant-Gravitas/AutoGPT-Code-Ability.git
synced 2026-11-10 16:11:28 -10:00
* Fix unimplemented function semantic --------- Co-authored-by: majdyz <[email protected]> Co-authored-by: majdyz <[email protected]> Co-authored-by: Swifty <[email protected]>
145 lines
5.0 KiB
Python
145 lines
5.0 KiB
Python
import asyncio
|
|
import logging
|
|
import os
|
|
|
|
from prisma.enums import FunctionState
|
|
from prisma.models import APIRouteSpec, CompletedApp, Function, Specification
|
|
|
|
from codex.api_model import Identifiers
|
|
from codex.develop.compile import compile_route, create_app
|
|
from codex.develop.develop import DevelopAIBlock
|
|
|
|
RECURSION_DEPTH_LIMIT = int(os.environ.get("RECURSION_DEPTH_LIMIT", 3))
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def develop_application(ids: Identifiers, spec: Specification) -> CompletedApp:
|
|
"""
|
|
Develops an application based on the given identifiers and specification.
|
|
|
|
Args:
|
|
ids (Identifiers): The identifiers used for development.
|
|
spec (Specification): The specification of the application.
|
|
|
|
Returns:
|
|
CompletedApp: The completed application.
|
|
|
|
"""
|
|
compiled_routes = []
|
|
if spec.ApiRouteSpecs:
|
|
for api_route in spec.ApiRouteSpecs:
|
|
route_root_func = await develop_route(
|
|
[], ids, api_route, api_route.description, api_route.functionName
|
|
)
|
|
logger.info(f"Route function id: {route_root_func.id}")
|
|
compiled_route = await compile_route(ids, route_root_func, api_route)
|
|
compiled_routes.append(compiled_route)
|
|
|
|
return await create_app(ids, spec, compiled_routes)
|
|
|
|
|
|
async def develop_route(
|
|
generated_functions: list[
|
|
Function
|
|
], # TODO: remove this, replace with vector-lookup.
|
|
ids: Identifiers,
|
|
api_route: APIRouteSpec,
|
|
goal_description: str,
|
|
function_name: str,
|
|
function_id: str = None,
|
|
function_template: str = None,
|
|
depth: int = 0,
|
|
) -> Function:
|
|
"""
|
|
Recursively develops a function and its child functions
|
|
based on the provided function definition and api route spec.
|
|
|
|
Args:
|
|
generated_functions (list[Function]): The list of already generated functions, used to promote function re-use.
|
|
ids (Identifiers): The identifiers for the function.
|
|
api_route (APIRouteSpec): The API route specification.
|
|
goal_description (str): The high-level goal of the function to create.
|
|
function_name (str): The name of the function to create.
|
|
function_id (str): The id of the function to create. If not provided, a new root-function will be created.
|
|
function_template (str): The docstring/template of the function to create.
|
|
depth (int): The depth of the recursion.
|
|
|
|
Returns:
|
|
Function: The developed route function.
|
|
"""
|
|
logger.info(
|
|
f"Developing for route: {api_route.path} - Func: {function_name}, depth: {depth}"
|
|
)
|
|
if depth >= RECURSION_DEPTH_LIMIT:
|
|
raise ValueError("Recursion depth exceeded")
|
|
|
|
route_function: Function = await DevelopAIBlock().invoke(
|
|
ids=ids,
|
|
invoke_params={
|
|
"function_name": function_name,
|
|
"goal": goal_description,
|
|
"function_signature": function_template,
|
|
"provided_functions": [
|
|
f.template
|
|
for f in generated_functions
|
|
if f.functionName != function_name and f.parentFunctionId
|
|
],
|
|
# api_route is not used by the prompt, but is used by the function
|
|
"api_route": api_route,
|
|
# function_id is used, so we can update the function with the implementation
|
|
"function_id": function_id,
|
|
"allow_stub": depth < RECURSION_DEPTH_LIMIT,
|
|
},
|
|
)
|
|
|
|
if route_function.ChildFunction:
|
|
generated_functions.extend(route_function.ChildFunction)
|
|
logger.info(f"\tDeveloping {len(route_function.ChildFunction)} child functions")
|
|
tasks = [
|
|
develop_route(
|
|
ids=ids,
|
|
goal_description=goal_description,
|
|
function_id=child.id,
|
|
function_name=child.functionName,
|
|
function_template=child.template,
|
|
api_route=api_route,
|
|
depth=depth + 1,
|
|
generated_functions=generated_functions,
|
|
)
|
|
for child in route_function.ChildFunction
|
|
if child.state == FunctionState.DEFINITION
|
|
]
|
|
await asyncio.gather(*tasks)
|
|
else:
|
|
logger.info(f"❌ No child functions to develop")
|
|
logger.debug(route_function.rawCode)
|
|
return route_function
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import asyncio
|
|
|
|
import prisma
|
|
from prisma.models import APIRouteSpec
|
|
|
|
import codex.common.test_const as test_consts
|
|
from codex.common.ai_model import OpenAIChatClient
|
|
from codex.common.logging import setup_logging
|
|
from codex.requirements.database import get_latest_specification
|
|
|
|
OpenAIChatClient.configure({})
|
|
setup_logging(local=True)
|
|
client = prisma.Prisma(auto_register=True)
|
|
|
|
async def run_me():
|
|
await client.connect()
|
|
ids = test_consts.identifier_1
|
|
spec = await get_latest_specification(ids.user_id, ids.app_id)
|
|
ans = await develop_application(ids=ids, spec=spec)
|
|
await client.disconnect()
|
|
return ans
|
|
|
|
ans = asyncio.run(run_me())
|
|
logger.info(ans)
|