feat: AI searches product part materials — finds products WITH Durotect
Added product_material filter to find_product_renders: - Searches cad_part_materials JSONB for materials assigned to CAD parts - find_product_renders(transparent_only=true, product_material="Durotect") → finds 9 products that naturally have Durotect parts with transparent renders Two material levels explained in system prompt rule 13: - product_material: materials from STEP/Excel (Durotect_M, Stahl, Bronze) - material_override: single material forced on ALL parts at render time AI now searches product_material FIRST when user asks "with Durotect material" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,7 +42,8 @@ RULES:
|
||||
10. Material system: Materials have SCHAEFFLER library names (e.g. SCHAEFFLER_020101_Durotect-Blue). Common names like "Durotect", "Stahl", "Bronze" are aliases that map to these library names. When the user asks for a material by a common name, use list_materials to find the correct SCHAEFFLER name, then use that for material_override.
|
||||
11. When setting material_override, always use the full SCHAEFFLER library name (e.g. SCHAEFFLER_020101_Durotect-Blue), never the alias.
|
||||
12. When mentioning a product, ALWAYS link to it: [ProductName](/products/UUID). When mentioning an order, link to it: [OrderNumber](/orders/UUID). This makes the response navigable.
|
||||
13. When searching for renders with multiple criteria (e.g. "transparent + Durotect"), search step by step: first find transparent renders (there are many), then check if any have the requested material. If no exact match exists, show the best available transparent render and explain that the specific material hasn't been rendered yet, then offer to create one. NEVER say "no renders found" when there ARE transparent renders — show what exists and explain what's missing."""
|
||||
13. Materials exist at TWO levels: (a) product_material — materials assigned to the product's CAD parts (from STEP/Excel import, e.g. "Durotect_M", "Stahl"), and (b) material_override — a single material applied to ALL parts at render time. When user asks for a product "with Durotect material", search product_material FIRST (products that naturally have Durotect parts). Only use material_override filter if they specifically say "override" or "alle Teile in".
|
||||
14. NEVER say "no renders found" when renders DO exist. If no exact match, show the closest match and explain what's different."""
|
||||
|
||||
# ── Tool definitions (OpenAI function-calling schema) ────────────────────────
|
||||
|
||||
@@ -287,7 +288,12 @@ TOOLS = [
|
||||
},
|
||||
"material_override": {
|
||||
"type": "string",
|
||||
"description": "Filter by material override (partial match). E.g. 'Durotect' to find renders using Durotect material.",
|
||||
"description": "Filter by material override applied at render time (partial match).",
|
||||
"default": "",
|
||||
},
|
||||
"product_material": {
|
||||
"type": "string",
|
||||
"description": "Filter by material assigned to the product's CAD parts (partial match). Use this to find products that naturally HAVE a specific material (e.g. 'Durotect', 'Bronze', 'Kunststoff'). This searches the product's cad_part_materials, NOT the render override.",
|
||||
"default": "",
|
||||
},
|
||||
},
|
||||
@@ -706,7 +712,7 @@ async def _tool_list_materials(db: AsyncSession, tenant_id: str, query: str = ""
|
||||
async def _tool_find_product_renders(
|
||||
db: AsyncSession, tenant_id: str,
|
||||
product_name: str = "", product_id: str = "", transparent_only: bool = False,
|
||||
material_override: str = "",
|
||||
material_override: str = "", product_material: str = "",
|
||||
) -> str:
|
||||
"""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"]
|
||||
@@ -725,6 +731,14 @@ async def _tool_find_product_renders(
|
||||
if material_override:
|
||||
conditions.append("(ol.material_override ILIKE :mat OR ot.material_override ILIKE :mat)")
|
||||
params["mat"] = f"%{material_override}%"
|
||||
if product_material:
|
||||
conditions.append("""
|
||||
EXISTS (
|
||||
SELECT 1 FROM jsonb_array_elements(p.cad_part_materials) cpm
|
||||
WHERE cpm->>'material' ILIKE :pmat
|
||||
)
|
||||
""")
|
||||
params["pmat"] = f"%{product_material}%"
|
||||
|
||||
where = " AND ".join(conditions)
|
||||
sql = f"""
|
||||
|
||||
Reference in New Issue
Block a user