# Using PydanticTaskTemplate for AIKP Development ## Introduction In the OCLI framework, the `PydanticTaskTemplate` provides a declarative way to define Task and Recipe structures using [Pydantic](https://docs.pydantic.dev/) models. This approach offers strong type safety and automated validation. ## The Template Object The **only mandatory requirement** for an AIKP to be recognized by OCLI is the presence of a `Template` class within the module path specified when creating a task (e.g., `task create --template ocli.aikp.your_module`). When using the Pydantic-based approach, your `Template` class inherits from `PydanticTaskTemplate` and must bind a `TaskSchema` and a `RecipeSchema`. ```python from ocli.classes.pydantic_task_template import PydanticTaskTemplate class Template(PydanticTaskTemplate[YourTaskSchema, YourRecipeSchema]): TaskSchema = YourTaskSchema RecipeSchema = YourRecipeSchema # Optional: override hooks like update_recipe or cli_task_mount ``` There are no strict requirements for where these schemas or your CLI commands are defined; they can be defined in the same file as the `Template` class, or imported from any other module. ## 1. Defining Schemas Schemas are the core of the Pydantic approach. They define the data structure and validation rules for your AIKP. ### TaskSchema The `TaskSchema` must inherit from `ocli.classes.task.TaskHeadSchema`. It defines the fields configurable via `task set`. ```python from pydantic import ConfigDict, Field from ocli.classes.task import TaskHeadSchema class YourTaskSchema(TaskHeadSchema): model_config = ConfigDict(validate_assignment=True, extra='allow') template: Literal['your.template.path'] = 'your.template.path' custom_parameter: int = Field(10, ge=0) # Add other fields as needed ``` ### RecipeSchema The `RecipeSchema` must inherit from `ocli.ai.recipe_head_schema.RecipeHeadSchema`. This model defines the structure of the final recipe JSON. ```python from ocli.ai.recipe_head_schema import RecipeHeadSchema, RecipeType, RecipeKind class YourRecipeSchema(RecipeHeadSchema): type: RecipeType = RecipeType.YourType kind: RecipeKind = RecipeKind.YourKind custom_parameter: int | None = None ``` ## 2. Implementing the Template The `Template` class orchestrates the interaction between the Task config and the generated Recipe. The primary hook for this is `update_recipe`. ```python from ocli.pro.helpers.task_helpers import updates_metadata_preset class Template(PydanticTaskTemplate[YourTaskSchema, YourRecipeSchema]): TaskSchema = YourTaskSchema RecipeSchema = YourRecipeSchema @classmethod @updates_metadata_preset def update_recipe(cls, task: Task, recipe: dict, roi: dict | None = None) -> list[str]: # Populate standard fields (DATADIR, OUTDIR) and validate errors = super().update_recipe(task, recipe, roi) try: # Type-safe access to task configuration task_config = YourTaskSchema.model_validate(task.config) # Map task configuration to recipe properties type-safely recipe_model = YourRecipeSchema(**recipe, custom_parameter=task_config.custom_parameter) # Update the original dictionary with validated/formatted data recipe.update(recipe_model.model_dump(mode="json", exclude_unset=True, by_alias=True)) except Exception as e: errors.append(str(e)) return errors ``` ## Key Benefits * **Declarative Validation**: Use Pydantic's native features (types, `Field` constraints, `@validator`) to enforce rules instead of manual `if/else` checks. * **Automated Recipe Sync**: `PydanticTaskTemplate` automatically handles schema validation for recipes, eliminating the need for a separate `recipe_schema.json`. * **Flexibility**: You are free to structure your code across one or many files; OCLI only cares about finding the `Template` object at the module path. * **Builder Pattern & Resilience**: `PydanticTaskTemplate` treats your `TaskSchema` as a builder. This means tasks can be created and updated incrementally via `task set` even if they are in an "invalid" or incomplete state. The framework only enforces strict schema compliance when it's time to generate a recipe, allowing for a flexible, interactive configuration workflow.