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>
This commit is contained in:
2026-03-15 14:50:03 +01:00
parent 48b5287baf
commit d37dd073bd
2 changed files with 67 additions and 4 deletions
+54 -2
View File
@@ -682,8 +682,60 @@ async def chat_with_agent(
# Build context-aware system prompt
system_content = SYSTEM_PROMPT
if context_type and context_id:
system_content += f"\n\nCurrent context: {context_type} {context_id}"
# Load entity details for the current page context
if context_type == "order" and context_id:
try:
ctx_result = await db.execute(
text("""
SELECT o.order_number, o.status, o.notes, o.created_at,
COUNT(ol.id) AS line_count,
COUNT(ol.id) FILTER (WHERE ol.render_status = 'completed') AS completed,
COUNT(ol.id) FILTER (WHERE ol.render_status = 'processing') AS processing,
COUNT(ol.id) FILTER (WHERE ol.render_status = 'failed') AS failed,
COUNT(ol.id) FILTER (WHERE ol.render_status = 'pending') AS pending
FROM orders o
LEFT JOIN order_lines ol ON ol.order_id = o.id
WHERE o.id = :ctx_id AND o.tenant_id = :tid
GROUP BY o.id
"""),
{"ctx_id": context_id, "tid": tenant_id},
)
row = ctx_result.mappings().first()
if row:
system_content += (
f"\n\nThe user is currently viewing order {row['order_number']} "
f"(ID: {context_id}, status: {row['status']}, "
f"{row['line_count']} lines: {row['completed']} completed, "
f"{row['processing']} processing, {row['failed']} failed, "
f"{row['pending']} pending). "
f"When the user says 'this order' or 'current order', they mean {row['order_number']} ({context_id})."
)
except Exception:
system_content += f"\n\nThe user is viewing order {context_id}."
elif context_type == "product" and context_id:
try:
ctx_result = await db.execute(
text("""
SELECT p.name, p.pim_id, p.category_key, p.baureihe,
CASE WHEN p.cad_file_id IS NOT NULL THEN true ELSE false END AS has_step
FROM products p
WHERE p.id = :ctx_id AND p.tenant_id = :tid
"""),
{"ctx_id": context_id, "tid": tenant_id},
)
row = ctx_result.mappings().first()
if row:
system_content += (
f"\n\nThe user is currently viewing product '{row['name']}' "
f"(ID: {context_id}, PIM-ID: {row['pim_id']}, "
f"category: {row['category_key']}, "
f"has STEP: {row['has_step']}). "
f"When the user says 'this product' or 'current product', they mean '{row['name']}' ({context_id})."
)
except Exception:
system_content += f"\n\nThe user is viewing product {context_id}."
system_content += f"\n\nThe user's tenant_id is '{tenant_id}'. Always filter queries by this tenant_id."
messages: list[dict] = [{"role": "system", "content": system_content}]