Commit Graph

17 Commits

Author SHA1 Message Date
Hartmut feef2a0827 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>
2026-03-16 10:47:01 +01:00
Hartmut 9c6b210d51 fix: AI agent shows best available render when exact match not found
Rule 13: when searching with multiple criteria (transparent + Durotect),
decompose the search. Show what exists (1220 transparent renders) and
explain what's missing (no Durotect material applied). Never say
"no renders found" when transparent renders DO exist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:43:01 +01:00
Hartmut 54522a63d4 feat: render metadata from render_log for past renderings
find_product_renders now reads actual render metadata from the
render_log JSONB (stored at render time) via COALESCE fallback:
- engine: render_log.engine_used > render_log.engine > output_type setting
- width/height: render_log > output_type.render_settings
- samples: render_log > output_type.render_settings
- render_type: still/turntable/cinematic from render_log.type
- has_template: whether a .blend template was used

All past renderings now have correct metadata without re-processing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:35:19 +01:00
Hartmut 86921bacbd 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>
2026-03-16 10:24:02 +01:00
Hartmut 59f83f10ad fix: AI agent must confirm before ANY write action including overrides
Explicitly listed all write tools that require confirmation:
create_order, dispatch_renders, set_material_override, set_render_overrides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:14:48 +01:00
Hartmut 8897afdebb fix: AI agent must confirm before creating orders or dispatching renders
Split rules into read-only vs write actions:
- READ (search, list, show images, status): execute immediately
- WRITE (create orders, dispatch, set overrides): ALWAYS ask for
  confirmation before executing

Prevents accidental render job creation from casual questions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:11:52 +01:00
Hartmut 20bcdee2a2 feat: AI agent links to products and orders in responses
System prompt rule 12: always format product mentions as
[ProductName](/products/UUID) and orders as [OrderNumber](/orders/UUID).

ReactMarkdown in ChatPanel already renders these as clickable links
with accent color styling, so users can navigate directly from chat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:07:44 +01:00
Hartmut ef4c8eefc9 feat: AI agent knows material library — list_materials tool with alias search
Added list_materials tool to the chat agent:
- Searches SCHAEFFLER library materials by name, description, or alias
- Returns material name + schaeffler_code + aliases
- Enables: "zeig mir ein Bild mit Durotect-Material" → agent searches
  for "durotect" → finds SCHAEFFLER_020101_Durotect-Blue → uses as
  material_override

System prompt updated with rules 10-11:
- Explains alias → library material mapping
- Always use full SCHAEFFLER name for material_override

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:05:05 +01:00
Hartmut 0dfadbfd56 fix: make AI agent proactive — never ask for info it can look up
System prompt rewritten with explicit RULES:
- Never ask user for info you can query yourself
- "Any product" / "beliebig" → just pick one, don't ask back
- Execute immediately, no confirmation needed
- Be concise, short answers preferred

find_product_renders tool:
- No longer requires product_name or product_id
- Call with empty params → returns any recent renders
- Enables "show me any render with transparent bg"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:56:21 +01:00
Hartmut 29f7103a8b feat: chat agent can find and show existing product renders
Added find_product_renders tool to the AI agent:
- Searches completed renders by product name/ID
- Returns viewable image URLs (relative paths)
- Supports transparent_only filter
- AI formats results as Markdown images/links in chat

Frontend:
- ChatPanel ReactMarkdown renders <img> and <a> tags
- Images shown inline (max 200px height, rounded, bordered)
- Links open in new tab with accent color

System prompt updated to instruct AI to use Markdown image syntax
when showing renders: ![description](/renders/...)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:52:45 +01:00
Hartmut cfccdd5397 feat: rich product metadata extraction from STEP files
Extract volume, surface area, part count, assembly hierarchy, and
complexity from STEP files via OCC B-rep analysis.

Backend:
- extract_rich_metadata() in step_processor.py: computes per-part volume
  (BRepGProp), surface area, triangle/vertex count, assembly depth,
  instance count, complexity score, largest part identification
- cad_metadata JSONB column on Product model (DB migration)
- Auto-populated during STEP processing (non-fatal, 10s timeout)
- Also stored in cad_files.mesh_attributes["rich_metadata"]
- Batch re-extract endpoint: POST /admin/settings/reextract-rich-metadata

AI Agent:
- search_products returns part_count, volume_cm3, complexity, largest_part
- query_database tool description documents cad_metadata schema

Frontend:
- ProductDetail page: CAD Metadata section with stat cards
  (parts, volume, surface area, complexity, triangles, assembly depth)
- Admin System Tools: "Re-extract Rich Metadata" button for backfill

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:49:50 +01:00
Hartmut 0ffc86589a fix: chat agent auth, auto-submit/dispatch, no confirmation prompts
- All httpx tool calls use real user_id instead of uuid(int=0) for
  service token — fixes 401 Unauthorized on dispatch/override
- create_order auto-submits and auto-dispatches in one step
- System prompt updated: execute immediately without asking for
  confirmation, respond in user's language
- Product search returns CAD dimensions (dim_x/y/z_mm)
- query_database tool description includes cad_files schema

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:59:53 +01:00
Hartmut f70a09886a feat: expose CAD dimensions (mm) in chat agent tools
- search_products now returns dim_x_mm, dim_y_mm, dim_z_mm from
  cad_files.mesh_attributes->'dimensions_mm'
- query_database tool description updated with cad_files schema
  including mesh_attributes->'dimensions_mm' path
- AI can now answer "what's the biggest product?" using real dimensions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:05:37 +01:00
Hartmut d37dd073bd feat: chat agent knows current page context (order/product)
Frontend: Layout extracts order/product UUID from URL path and passes
to ChatPanel as contextType/contextId. When on /orders/{uuid}, the
chat knows which order you're viewing.

Backend: System prompt now loads actual entity data for the context:
- Order: order_number, status, line counts (completed/processing/failed)
- Product: name, PIM-ID, category, STEP file status

The AI understands "this order", "current product" etc. Example:
"What's the status of this order?" → agent knows you mean SA-2026-00164

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:50:03 +01:00
Hartmut 48b5287baf fix: rollback DB session after failed tool execution in chat agent
When a tool like query_database fails (e.g., bad column name), the
SQLAlchemy session enters a failed transaction state. Subsequent
operations (like saving the assistant response) then also fail with
InFailedSQLTransactionError.

Fix: rollback the session in the except block of _execute_tool().
Also improved query_database tool description with correct column
names (category_key not category) to help the AI write valid SQL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:33 +01:00
Hartmut 502e2d0387 fix: use max_completion_tokens instead of max_tokens for GPT-4o
Azure OpenAI GPT-4o and newer models require 'max_completion_tokens'
instead of 'max_tokens'. Fixed in all 3 services:
- chat_service.py (2 call sites)
- azure_ai.py (validation service)
- tenants/router.py (test connection endpoint)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:20:40 +01:00
Hartmut 59ce61098c feat: tenant AI chat agent with function calling
Actionable AI assistant that uses per-tenant Azure OpenAI credentials
to execute natural language commands against the render pipeline.

Backend:
- ChatMessage model + migration (session-based conversations)
- Chat service with 10 OpenAI function-calling tools:
  list_orders, search_products, create_order, dispatch_renders,
  get_order_status, set_material_override, set_render_overrides,
  get_render_stats, check_materials, query_database
- All tools tenant-scoped (queries filtered by tenant_id)
- Write operations use httpx to call backend API internally
- Chat API: POST /chat/messages, GET /chat/sessions, DELETE session
- Conversation history preserved in DB (last 50 messages per session)

Frontend:
- Slide-out ChatPanel (right side, w-96, animated)
- User/assistant message styling with avatars and timestamps
- Session management (new chat, session history, delete)
- Typing indicator while waiting for AI response
- Floating chat button in bottom-right corner
- Error state for unconfigured AI tenants

Example: "Render all Kugellager products as WebP at 1024x1024"
→ Agent calls search_products + create_order + dispatch_renders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:46:21 +01:00