LaelaZ's picture
Deploy SupportCopilot to HF Spaces (Docker)
8981bf6 verified
{# HTML fragment returned by POST /chat and appended to the chat thread by htmx. #}
{# ----- User message (right) ----- #}
<div class="sc-fade flex items-start justify-end gap-2.5">
<div class="sc-bubble sc-bubble--user">{{ message }}</div>
<span class="mt-0.5 grid h-8 w-8 shrink-0 place-items-center rounded-full bg-sand-200 text-sand-500 dark:bg-sand-700 dark:text-sand-300">
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
</span>
</div>
{# ----- Agent reply (left) ----- #}
<div class="sc-fade flex items-start gap-2.5">
<span class="sc-grad mt-0.5 grid h-8 w-8 shrink-0 place-items-center rounded-full text-white">
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>
</span>
<div class="min-w-0 flex-1 space-y-2.5">
{# Status / intent / confidence badges #}
<div class="flex flex-wrap items-center gap-1.5">
{% if resp.escalated %}
<span class="sc-badge sc-badge--escalate">
<svg class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 11h-6"/></svg>
Escalated to human
</span>
{% elif resp.auto_resolved %}
<span class="sc-badge sc-badge--resolved">
<svg class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
Auto-resolved
</span>
{% endif %}
<span class="sc-badge sc-badge--neutral">{{ resp.intent | replace('_', ' ') }}</span>
</div>
{# Answer bubble #}
<div class="sc-bubble sc-bubble--agent text-sand-700 dark:text-sand-200">
{{ resp.answer }}
</div>
{# Confidence meter #}
<div class="flex items-center gap-2 pl-1">
<span class="text-[11px] font-semibold text-sand-400 dark:text-sand-500">Confidence</span>
<div class="sc-meter w-24"><span style="width: {{ (resp.confidence * 100) | round(0, 'floor') }}%"></span></div>
<span class="text-[11px] font-bold text-sand-500 dark:text-sand-400">{{ '%.0f' % (resp.confidence * 100) }}%</span>
</div>
{# Refund / escalation decision card #}
{% if resp.refund %}
<div class="sc-decision sc-decision--{{ resp.refund.outcome }}">
<div class="flex items-center gap-2">
{% if resp.refund.outcome == 'approve' %}
<svg class="h-4 w-4 text-emerald-600 dark:text-emerald-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
{% elif resp.refund.outcome == 'deny' %}
<svg class="h-4 w-4 text-red-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
{% else %}
<svg class="h-4 w-4 text-amber-600 dark:text-amber-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
{% endif %}
<span class="text-sm font-bold text-sand-800 dark:text-sand-100">
Refund decision: {{ resp.refund.outcome | upper }}
{% if resp.refund.outcome == 'approve' %}
· ${{ '%.2f' % resp.refund.refund_amount }}
{% if resp.refund.fee_applied %}<span class="font-normal text-sand-500 dark:text-sand-400">(after ${{ '%.2f' % resp.refund.fee_applied }} return-shipping fee)</span>{% endif %}
{% endif %}
</span>
</div>
<p class="mt-1.5 text-sm text-sand-600 dark:text-sand-300">{{ resp.refund.reason }}</p>
<div class="mt-2 flex items-center gap-1.5 text-xs text-sand-500 dark:text-sand-400">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
Per <span class="font-semibold text-sand-600 dark:text-sand-300">{{ resp.refund.policy_citation }}</span>
</div>
</div>
{% endif %}
{# Escalation explainer card (no refund object but escalated) #}
{% if resp.escalated and not resp.refund %}
<div class="sc-decision sc-decision--escalate flex items-start gap-2">
<svg class="mt-0.5 h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.81.36 1.6.7 2.34a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.74-1.27a2 2 0 0 1 2.11-.45c.74.34 1.53.57 2.34.7A2 2 0 0 1 22 16.92z"/></svg>
<p class="text-sm text-sand-600 dark:text-sand-300">
Handed off to a human specialist — the agent escalates sensitive or low-confidence
cases instead of guessing.
</p>
</div>
{% endif %}
{# Citations as chips #}
{% if resp.citations %}
<div>
<p class="mb-1.5 flex items-center gap-1.5 text-xs font-semibold text-sand-400 dark:text-sand-500">
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
Sources ({{ resp.citations | length }})
</p>
<div class="flex flex-wrap gap-1.5">
{% for c in resp.citations %}
<span class="sc-chip sc-chip--{{ c.kind }}" title="{{ c.snippet }}">
<span class="sc-chip-dot"></span>{{ c.title }}
</span>
{% endfor %}
</div>
</div>
{% endif %}
</div>
</div>