Commit Graph

210 Commits

Author SHA1 Message Date
Hartmut 22981af1d2 docs: add workflow worker orchestration 2026-04-08 21:14:34 +02:00
Hartmut 7e100ed334 feat: expose graph still workflow in editor 2026-04-08 11:16:47 +02:00
Hartmut ffcaef4659 feat: add workflow output comparison tooling 2026-04-07 11:45:28 +02:00
Hartmut f43f1e7420 feat: add duplicate-safe workflow shadow dispatch 2026-04-07 11:35:32 +02:00
Hartmut 26046fb2d6 feat: expose workflow execution modes in editor 2026-04-07 11:10:58 +02:00
Hartmut f9d4da52b9 feat: add graph workflow fallback and retry metadata 2026-04-07 10:56:45 +02:00
Hartmut c17b7d2e8f feat: execute workflow bridge nodes in graph runtime 2026-04-07 10:42:59 +02:00
Hartmut 6ad34ceed2 feat: add workflow run dispatch foundation 2026-04-07 10:11:46 +02:00
Hartmut ab1b220e79 test: close workflow phase 3 executor coverage 2026-04-07 10:00:38 +02:00
Hartmut 98b3eadcb2 feat: extract workflow notifications phase 3 2026-04-07 09:57:39 +02:00
Hartmut 160c198bb3 feat: extract workflow output save phase 3 2026-04-07 09:50:58 +02:00
Hartmut 9c93ecef49 feat: extract workflow bbox services phase 3 2026-04-07 09:42:06 +02:00
Hartmut 8f8d2e68b7 feat: extract workflow material services phase 3 2026-04-07 09:22:24 +02:00
Hartmut e3cda1c9f7 feat: extract workflow runtime phase 3 foundation 2026-04-07 09:09:40 +02:00
Hartmut 56ee5fc5bf feat: add workflow node registry phase 2 2026-04-07 08:59:27 +02:00
Hartmut 63e35ce807 feat: stabilize workflow phase 1 foundation 2026-04-07 08:48:48 +02:00
Hartmut bc9ab5f864 docs: add workflow migration plan and checkpoint current state 2026-04-07 08:38:16 +02:00
Hartmut 2a00abe91f fix: restore historical order visibility for HartOMat admins 2026-04-06 19:24:09 +02:00
Hartmut f13cb489c1 fix: migrate runtime data to native hartomat storage 2026-04-06 18:09:51 +02:00
Hartmut 8990b80abf fix: restore existing runtime data volumes 2026-04-06 18:01:15 +02:00
Hartmut 448996b546 fix: stabilize HartOMat runtime startup 2026-04-06 13:10:51 +02:00
Hartmut 6f6d6efe74 chore: add HartOMat cleanup helper 2026-04-06 13:00:14 +02:00
Hartmut fcc51b6cb3 chore: smooth local path references 2026-04-06 12:49:36 +02:00
Hartmut b795f0e6d6 refactor: rebrand project to HartOMat 2026-04-06 12:45:47 +02:00
Hartmut fa7093307a chore: snapshot before HartOMat rebrand 2026-04-06 12:41:44 +02:00
Hartmut 7d27ffc116 fix: remove 2.0 from Hartomatisierung
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:27:47 +01:00
Hartmut 30ce747b43 rebrand: Schaeffler Automat → Hart.O.Mat — Hartomatisierung 2.0
- Sidebar: Hart.O.Mat + Hartomatisierung 2.0
- Logo badge: S → H
- Mobile header: Hart.O.Mat
- Page title: Hart.O.Mat — Hartomatisierung 2.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:25:58 +01:00
Hartmut 9cb947b1cd rename: AI Assistant → HartBOT
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:13:38 +01:00
Hartmut 8290e16b2d fix: chat panel doesn't overlap main content, links use client-side nav
Layout: main content gets mr-96 (margin-right) when chat is open,
pushing the page content left so the chat panel sits alongside it
without overlapping. Smooth 300ms transition.

ChatPanel: internal links (/products/..., /orders/...) now use
React Router navigate() instead of target="_blank" — clicking a
product link in the chat navigates without reloading the page,
keeping the chat panel open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:10:58 +01:00
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 02669c395c fix: cinematic camera accounts for output aspect ratio
For 16:9 (1280x720), vertical FOV is narrower than horizontal —
products could be clipped top/bottom. Now applies an aspect ratio
correction factor to camera distance: wider formats push camera
further back proportionally.

Still render (_blender_camera.py) already handled this via
min(fov_h, fov_v); cinematic now has equivalent correction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 08:15:10 +01:00
Hartmut 81eb1f9eae fix: cinematic camera distances — no clipping, full product always visible
Redesigned all 3 segments to keep distance > 3× bsphere_radius:
- Segment 1: 3.5× → 3.0× (establishing orbit, 50mm)
- Segment 2: 3.0× → 3.2× (low angle sweep, 50→65mm)
- Segment 3: 3.2× → 4.0× (crane up, 50→40mm)

Removed: detail closeup (was 1.5-1.8×, caused object clipping),
telephoto 85mm (caused extreme close framing), DOF (not needed at safe distance)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:21:48 +01:00
Hartmut 3a815a85c5 fix: Blender 5.0 Action.fcurves API change — safe LINEAR keyframe setting
Blender 5.0 renamed Action.fcurves. Now tries fcurves first, falls
back to channels, and wraps in try/except so the render proceeds
even if LINEAR interpolation can't be set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:05:58 +01:00
Hartmut c159bff2df fix: clean frames directory before cinematic/turntable re-render
Old frame PNGs from previous render attempts persisted in the frames
directory, causing FFmpeg to stitch the wrong number of frames.
Now rmtree's the directory before creating it fresh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 22:02:20 +01:00
Hartmut 458c6cd813 refactor: cinematic render — linear keyframes, 3 segments, 250 frames, white bg
Changes per user feedback:
- Keyframe interpolation: BEZIER → LINEAR (all fcurves set to LINEAR)
- Removed segment 4 (closeup) — now 3 segments only
- Frame count: 480 → 250 (10 seconds at 25fps)
- FPS: 24 → 25
- Easing removed — pure linear interpolation between segment params
- White background by default (World node Color = white)
- Transparent bg still available as override

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:57:42 +01:00
Hartmut 75ad397c09 fix: unbuffered stdout for live cinematic frame progress
Two fixes for frame progress not appearing in frontend:
1. Added flush=True to all print() calls in cinematic_render.py
2. Set PYTHONUNBUFFERED=1 in subprocess environment

Without these, Python buffers stdout inside Blender, so all frame
progress lines arrive in a batch after the process exits instead
of streaming line-by-line during rendering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:53:26 +01:00
Hartmut e0714854d2 fix: stream Blender frame output to frontend for cinematic renders
The filter only matched [cinematic_render] tag but Blender outputs its
own "Saved: frame_NNNN.png" lines per frame. Now also matches "Saved:"
lines, extracts the frame number, and formats as:
  [cinematic_render] Frame 84/480 rendered

This shows live frame progress in the LiveRenderLog on the frontend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:42:36 +01:00
Hartmut caffe7809c feat: live frame progress streaming for cinematic renders
Replaced communicate() (blocking) with selectors-based line-by-line
stdout streaming — same pattern as still render. Each frame now
streams live to the frontend:

  [cinematic_render] Frame 42/480 -- 55.3s elapsed (0.76 fps)

Pipeline: Blender stdout → log_callback → emit() → Redis →
LiveRenderLog poll (2s) → frontend display

Also added log_callback parameter to cinematic render task call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:39:41 +01:00
Hartmut e26d76154b fix: cinematic render arg order — match turntable positional layout
The service was sending (glb, frames_dir, width, height, engine, samples...)
but the script expected turntable order (glb, frames_dir, frame_count, degrees,
width, height, engine, samples...). Fixed by adding frame_count and degrees
placeholders to match the expected positional layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:32:34 +01:00
Hartmut f22b963be9 feat: cinematic highlight render — 20s procedural camera animation
New render type: 4-segment cinematic camera animation (480 frames @ 24fps)
for professional product highlight videos.

Camera sequence:
1. Establishing (5s): slow 45° orbit + push-in, 50mm lens
2. Detail sweep (5s): low-angle close arc, 85mm telephoto, shallow DOF
3. Crane up (5s): rising 30°→60°, 35mm wide reveal, pull-back
4. Hero close (5s): push-in to beauty angle, 65mm, smooth ease-out

Technical:
- cinematic_render.py: procedural camera from bounding sphere, cubic easing,
  per-frame keyframes (location, rotation, focal length, DOF)
- render_cinematic_to_file(): service function (same pattern as turntable)
- Pipeline routing: render_settings.cinematic flag → cinematic path
- Depth of field enabled (f-stop scales with product size)
- use_persistent_data for BVH caching between frames
- Same material/template/USD pipeline as turntable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:25:56 +01:00
Hartmut c82f2a894d fix: invalidate orders list after deleting an order
The kanban board kept showing deleted orders until manual reload.
Added qc.invalidateQueries for 'orders' and qc.removeQueries for
the deleted order's detail cache on delete success.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:49:46 +01:00
Hartmut 6f7c001376 feat: persist chat session across page reloads
Session ID saved to localStorage (schaeffler-chat-session).
On mount, restores the last session and loads messages from DB.
"New Chat" clears the stored session.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:06:27 +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