feat: render metadata in find_product_renders — material, format, resolution
find_product_renders now returns full render job metadata: - material_override (effective: line override > output type override) - output_format (with render_overrides applied) - resolution (width x height) - engine, samples - order_number + order_id (for linking) - is_animation flag New material_override filter: search renders by material name (e.g. transparent_only=true, material_override="Durotect" finds renders with Durotect material on transparent background) AI can now answer: "Show me a transparent Durotect render" by filtering both transparency AND material in one query. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -284,6 +284,11 @@ TOOLS = [
|
|||||||
"description": "Only return renders with transparent background.",
|
"description": "Only return renders with transparent background.",
|
||||||
"default": False,
|
"default": False,
|
||||||
},
|
},
|
||||||
|
"material_override": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Filter by material override (partial match). E.g. 'Durotect' to find renders using Durotect material.",
|
||||||
|
"default": "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -700,6 +705,7 @@ async def _tool_list_materials(db: AsyncSession, tenant_id: str, query: str = ""
|
|||||||
async def _tool_find_product_renders(
|
async def _tool_find_product_renders(
|
||||||
db: AsyncSession, tenant_id: str,
|
db: AsyncSession, tenant_id: str,
|
||||||
product_name: str = "", product_id: str = "", transparent_only: bool = False,
|
product_name: str = "", product_id: str = "", transparent_only: bool = False,
|
||||||
|
material_override: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Find existing render images for a product, returning viewable URLs."""
|
"""Find existing render images for a product, returning viewable URLs."""
|
||||||
conditions = ["o.tenant_id = :tenant_id", "ol.render_status = 'completed'", "ol.result_path IS NOT NULL"]
|
conditions = ["o.tenant_id = :tenant_id", "ol.render_status = 'completed'", "ol.result_path IS NOT NULL"]
|
||||||
@@ -715,13 +721,25 @@ async def _tool_find_product_renders(
|
|||||||
|
|
||||||
if transparent_only:
|
if transparent_only:
|
||||||
conditions.append("ot.transparent_bg = true")
|
conditions.append("ot.transparent_bg = true")
|
||||||
|
if material_override:
|
||||||
|
conditions.append("(ol.material_override ILIKE :mat OR ot.material_override ILIKE :mat)")
|
||||||
|
params["mat"] = f"%{material_override}%"
|
||||||
|
|
||||||
where = " AND ".join(conditions)
|
where = " AND ".join(conditions)
|
||||||
sql = f"""
|
sql = f"""
|
||||||
SELECT p.name AS product_name, p.id AS product_id,
|
SELECT p.name AS product_name, p.id AS product_id,
|
||||||
ot.name AS output_type, ot.transparent_bg,
|
ot.name AS output_type, ot.transparent_bg,
|
||||||
|
ot.output_format, ot.is_animation,
|
||||||
|
ot.material_override AS ot_material_override,
|
||||||
|
ot.render_settings->>'width' AS ot_width,
|
||||||
|
ot.render_settings->>'height' AS ot_height,
|
||||||
|
ot.render_settings->>'engine' AS ot_engine,
|
||||||
|
ot.render_settings->>'samples' AS ot_samples,
|
||||||
|
ol.material_override AS line_material_override,
|
||||||
|
ol.render_overrides,
|
||||||
ol.result_path, ol.id AS line_id,
|
ol.result_path, ol.id AS line_id,
|
||||||
ol.render_completed_at
|
ol.render_completed_at,
|
||||||
|
o.order_number, o.id AS order_id
|
||||||
FROM order_lines ol
|
FROM order_lines ol
|
||||||
JOIN orders o ON o.id = ol.order_id
|
JOIN orders o ON o.id = ol.order_id
|
||||||
JOIN products p ON p.id = ol.product_id
|
JOIN products p ON p.id = ol.product_id
|
||||||
@@ -734,7 +752,7 @@ async def _tool_find_product_renders(
|
|||||||
rows = result.mappings().all()
|
rows = result.mappings().all()
|
||||||
|
|
||||||
if not rows:
|
if not rows:
|
||||||
return json.dumps({"message": "No completed renders found for this product.", "renders": []})
|
return json.dumps({"message": "No completed renders found.", "renders": []})
|
||||||
|
|
||||||
renders = []
|
renders = []
|
||||||
for r in rows:
|
for r in rows:
|
||||||
@@ -746,18 +764,31 @@ async def _tool_find_product_renders(
|
|||||||
elif "/thumbnails/" in path:
|
elif "/thumbnails/" in path:
|
||||||
url = path[path.index("/thumbnails/"):]
|
url = path[path.index("/thumbnails/"):]
|
||||||
|
|
||||||
|
# Effective material override (line overrides output type)
|
||||||
|
material = r["line_material_override"] or r["ot_material_override"] or None
|
||||||
|
# Effective render overrides
|
||||||
|
overrides = r["render_overrides"] or {}
|
||||||
|
|
||||||
renders.append({
|
renders.append({
|
||||||
"product_name": r["product_name"],
|
"product_name": r["product_name"],
|
||||||
"product_id": str(r["product_id"]),
|
"product_id": str(r["product_id"]),
|
||||||
|
"order_number": r["order_number"],
|
||||||
|
"order_id": str(r["order_id"]),
|
||||||
"output_type": r["output_type"],
|
"output_type": r["output_type"],
|
||||||
|
"output_format": overrides.get("output_format") or r["output_format"],
|
||||||
"transparent_bg": r["transparent_bg"],
|
"transparent_bg": r["transparent_bg"],
|
||||||
|
"is_animation": r["is_animation"],
|
||||||
|
"resolution": f"{overrides.get('width') or r['ot_width'] or '?'}x{overrides.get('height') or r['ot_height'] or '?'}",
|
||||||
|
"engine": overrides.get("engine") or r["ot_engine"],
|
||||||
|
"samples": overrides.get("samples") or r["ot_samples"],
|
||||||
|
"material_override": material,
|
||||||
"image_url": url,
|
"image_url": url,
|
||||||
"line_id": str(r["line_id"]),
|
"line_id": str(r["line_id"]),
|
||||||
"rendered_at": str(r["render_completed_at"]),
|
"rendered_at": str(r["render_completed_at"]),
|
||||||
})
|
})
|
||||||
|
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
"message": f"Found {len(renders)} render(s). Show the user these image URLs as clickable links.",
|
"message": f"Found {len(renders)} render(s). Each has metadata about format, resolution, material override, transparency. Show image URLs as Markdown images or links.",
|
||||||
"renders": renders,
|
"renders": renders,
|
||||||
}, indent=2, default=str)
|
}, indent=2, default=str)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user