| """Cataloger agent: analyzes craft items and produces structured metadata.""" |
|
|
| from jinja2 import Template |
|
|
| from agents.llm import LLMClient |
| from agents.models import AgentTrace, CatalogerOutput |
|
|
| SYSTEM_PROMPT = ( |
| "You are a craft catalog expert. Analyze handmade craft items and " |
| "produce structured catalog entries.\n\n" |
| "You understand materials, techniques, and categories for: crochet, " |
| "painting, embroidery, sewing, stitching, and other handmade crafts.\n\n" |
| "Always respond with valid JSON." |
| ) |
|
|
| USER_TEMPLATE = Template( |
| "Analyze this {{ craft_type }} item and create a catalog entry.\n\n" |
| "Image description: {{ image_description }}\n" |
| "{% if user_notes %}Creator's notes: {{ user_notes }}{% endif %}\n\n" |
| "Categorize it with: category (e.g., 'home decor', 'fashion accessory', " |
| "'wall art'), sub_category (e.g., 'coaster', 'scarf', 'portrait'), " |
| "materials used, colors, estimated size, relevant tags for " |
| "searchability, and complexity level (simple/moderate/complex)." |
| ) |
|
|
|
|
| async def run( |
| llm: LLMClient, |
| image_description: str, |
| craft_type: str, |
| user_notes: str | None = None, |
| ) -> tuple[CatalogerOutput, AgentTrace]: |
| prompt = USER_TEMPLATE.render( |
| craft_type=craft_type, |
| image_description=image_description, |
| user_notes=user_notes, |
| ) |
| result, duration_ms = await llm.agenerate( |
| system=SYSTEM_PROMPT, |
| prompt=prompt, |
| output_schema=CatalogerOutput, |
| ) |
| trace = AgentTrace( |
| agent_name="cataloger", |
| input_text=prompt, |
| output_data=result.model_dump(), |
| duration_ms=duration_ms, |
| model_id=llm.model_id, |
| ) |
| return result, trace |
|
|