{% extends "solo/base_solo.html" %} {% block title %}Annotate · Solo Mode · Potato{% endblock %} {% block extra_head %} {% endblock %} {% block content %} {% if instance %}

Annotate

{% if stats %} {# Denominator is the full dataset size (stable). The old formula human_labeled + remaining collapsed to 0 once the background LLM had pre-labeled everything (remaining counts items unlabeled by human OR LLM), producing "Instance 1 of 0". #} Instance {{ stats.human_labeled + 1 }} of {{ stats.total }} {% endif %}
{% set atype = annotation_type or 'radio' %}
{# Whether the LLM's suggestion was on screen when the human answered, and whether the answer came from Accept. They split agreement into blind and shown, which is how anchoring is measured. #} {% if atype == 'span' %}
{{ instance.text }}
{% else %}
{{ instance.text }}
{% endif %} {% if llm_prediction %} {% set conf = (llm_prediction.confidence * 100)|int %} {% set qualifier = 'Low confidence' if llm_prediction.confidence < 0.5 else ('Moderate confidence' if llm_prediction.confidence < 0.8 else 'High confidence') %}
The model suggests {{ llm_prediction.label }}
{{ qualifier }}· {{ conf }}%
{% elif show_suggestion is defined and not show_suggestion %}

The suggestion is hidden for this item, so your answer can be compared with it blind. If you disagree, you'll see the model's label next.

{% else %} {# No LLM prediction for this instance yet. The background labeler may still be working (LLMs can be slow); show a live indicator and poll for the suggestion instead of leaving the row silently empty. #}
The model is still labeling this item… its suggestion will appear here in a moment.
{% endif %} {% if atype in ('text', 'textbox') %}
Type your answer
{% elif atype == 'span' %}
Pick a label, then highlight the matching text above. Repeat for each span.
{% for label in labels %} {% endfor %}
{% else %}
{% if atype == 'multiselect' %}Select all that apply (click to toggle){% else %}Pick a label (use number keys, or click){% endif %}
{% for label in labels %} {% endfor %}
{% endif %}
{% elif message %}
{% if phase in ('completed', 'final_validation', 'autonomous_labeling') %}

You're done with this batch

{% if phase == 'completed' %} The workflow is complete. Export your annotations from the dashboard. {% else %} {{ message }}. The model is taking it from here while the dataset finishes labeling. {% endif %}

{% else %}

Caught up for now

{{ message }}. New instances may appear shortly — check the dashboard for progress.

{% endif %} {% if stats %}
You labeled
{{ stats.human_labeled }}
Model labeled
{{ stats.llm_labeled }}
Agreement
{{ (stats.agreement_rate * 100)|int }}%
Remaining
{{ stats.remaining }}
{% endif %}
Go to dashboard
{% endif %} {% endblock %} {% block stats %} {# Drop redundant "Phase" row; lead with progress, which is what the user wants here. #} {% if stats %} {# The human's own progress against the full dataset. `remaining` counts items neither the human nor the LLM has labelled, so once the LLM had pre-labelled everything it read "0 / 0" with "Remaining 0" on the first item -- the same collapse the header counter had. #} {% set total = stats.total if stats.total is defined else stats.human_labeled + stats.remaining %}
Progress {{ stats.human_labeled }} / {{ total }}
Left for you {{ [total - stats.human_labeled, 0]|max }}
Model labeled {{ stats.llm_labeled }}
Agreement {{ (stats.agreement_rate * 100)|int }}%
{% else %} {{ super() }} {% endif %} {% endblock %} {% block sidebar_extra %} {% if labels and instance %}

Shortcuts

{% for label in labels[:9] %}
{{ loop.index }} {{ label }}
{% endfor %} {% if llm_prediction %}
A Accept model
{% endif %}
Enter Submit
{% endif %} {% endblock %} {% block extra_js %} {% if annotation_type == 'span' %} {% endif %} {% endblock %}