{% set header_subtitle = 'analysis results' %} {% include '_header.html' %}

{{ pipeline.name }}

Analysis Direction

{% if pipeline.default_context %} {% set ns_ctx = namespace(has_custom=false) %} {% for k, v in pipeline.default_context.items() %} {% if v is mapping and v.default is defined %} {% set actual_value = v.default %} {% set is_default = true %} {% else %} {% set actual_value = v %} {% set is_default = false %} {% endif %} {% if actual_value %}

{{ k }}: {{ actual_value }}{% if is_default %}*{% else %}{% set ns_ctx.has_custom = true %}{% endif %}

{% endif %} {% endfor %}

* default value

{% else %}

Using pipeline defaults.

{% endif %}

Results

{{ result.themes|length if result.themes else 0 }} themes

{{ result.codes|length if result.codes else 0 }} codes

Model

{% if pipeline.config.model_name %}

{{ pipeline.config.model_name }}

{% endif %}

{{ pipeline.config.document_paths|length }} documents

Source files: {{ pipeline.config.input_source or "files" }} ({{ pipeline.config.document_paths|length }})
{% if self_similarity and self_similarity.n_themes > 1 %} {% endif %} {% if verification_data %} {% endif %}
{% set ns = namespace(has_narrative=false) %} {% for report_key in pipeline.config.report_texts %} {# report_key can be 'node_name.slot_name' or just 'node_name' #} {% set node_name = report_key.split('.')[0] %} {% set slot_name = report_key.split('.')[1] if '.' in report_key else none %} {% if node_name in pipeline.nodes_dict and pipeline.nodes_dict[node_name].output %} {% set node = pipeline.nodes_dict[node_name] %} {% set node_result = node.result() %} {# Handle both dict (from JSON) and ChatterResult object (live) #} {% if node_result is mapping %} {% set chatter = node_result.get('chatter_result', {}) %} {% set results = chatter.get('results', {}) if chatter is mapping else {} %} {% else %} {# Live ChatterResult - get results directly from outputs #} {% set results = {} %} {% endif %} {# For live runs, check node.output directly #} {% set ns2 = namespace(narrative_text=none) %} {% if node.output and node.output is iterable and node.output[0] is defined %} {% set first_output = node.output[0] %} {# Live ChatterResult object #} {% if first_output.outputs is defined %} {% if slot_name and slot_name in first_output.outputs %} {% set slot_val = first_output.outputs[slot_name] %} {% if slot_val is string %} {% set ns2.narrative_text = slot_val %} {% endif %} {% else %} {% for iter_slot_name, slot_val in first_output.outputs.items() %} {% if slot_val is string %} {% set ns2.narrative_text = slot_val %} {% endif %} {% endfor %} {% endif %} {# Deserialized dict with results #} {% elif first_output is mapping and first_output.results is defined %} {% if slot_name and slot_name in first_output.results %} {% set slot_data = first_output.results[slot_name] %} {% if slot_data is mapping and slot_data.output is defined and slot_data.output is string %} {% set ns2.narrative_text = slot_data.output %} {% endif %} {% else %} {% for iter_slot_name, slot_data in first_output.results.items() %} {% if slot_data is mapping and slot_data.output is defined and slot_data.output is string %} {% set ns2.narrative_text = slot_data.output %} {% endif %} {% endfor %} {% endif %} {% endif %} {% endif %} {# Fallback: try the results dict from node.result() #} {% if not ns2.narrative_text and results %} {% if slot_name and slot_name in results %} {% set slot_data = results[slot_name] %} {% if slot_data is mapping and slot_data.get('output') is string %} {% set ns2.narrative_text = slot_data.get('output') %} {% endif %} {% else %} {% for iter_slot_name, slot_data in results.items() %} {% if slot_data is mapping and slot_data.get('output') is string %} {% set ns2.narrative_text = slot_data.get('output') %} {% endif %} {% endfor %} {% endif %} {% endif %} {% if ns2.narrative_text %} {% set ns.has_narrative = true %} {% set report_info = pipeline.config.report_texts[report_key] if pipeline.config.report_texts is mapping else {} %} {% set display_label = report_info.label if report_info is mapping and report_info.label else (slot_name or node_name)|title|replace('_', ' ') %} {% set display_description = report_info.description if report_info is mapping and report_info.description else none %}

{{ display_label }}

{% if display_description %}

{{ display_description }}

{% endif %}
{% markdown %} {{ ns2.narrative_text|safe }} {% endmarkdown %}
{% endif %} {% endif %} {% endfor %} {% if not ns.has_narrative %}

No narrative sections were generated by this pipeline.

{% endif %}

Themes

Click a theme to expand and see related codes and quotes.

{% if themes_with_codes %} {% for theme in themes_with_codes %} {% set theme_idx = loop.index0 %}
{{ theme.name|capitalize }}
{{ theme.description[:100] }}{% if theme.description|length > 100 %}...{% endif %}
{{ theme.related_codes|length }} codes {% if theme.total_quotes %} {{ theme.total_quotes }} quotes {% endif %}

{{ theme.description }}

{% if theme.related_codes %}
Related codes:
{% for code in theme.related_codes %}
{{ code.name }} {% set quotes = code.all_quotes or code.quotes or code.resolved_quotes or [] %} {% if quotes %} ({{ quotes|length }} quotes) {% endif %}
{% if quotes %}
{% for quote in quotes[:3] %}
"{{ quote.text|truncatewords(30) if quote.text else quote }}"
{% endfor %} {% if quotes|length > 3 %}
...and {{ quotes|length - 3 }} more
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %} {% else %} {% set themes_node = pipeline.nodes_dict.get('themes') %} {% if themes_node and themes_node.output %} {% set node_result = themes_node.result() %} {% set response_obj = node_result.response_obj if node_result else none %} {% set theme_list = response_obj.themes if response_obj and response_obj.themes is defined else [] %} {% for theme in theme_list %}
{{ theme.name|capitalize }}
{{ theme.description }}
{% if theme.code_slugs %}
{% for slug in theme.code_slugs %} {{ slug }} {% endfor %}
{% endif %}
{% endfor %} {% if not theme_list %}

No themes were generated.

{% endif %} {% else %}

Themes node has no output.

{% endif %} {% endif %}
{% if self_similarity and self_similarity.n_themes > 1 %}

Theme Overlap

This matrix shows how similar each theme is to every other theme. Click a cell to compare two themes.

{% for label in self_similarity.short_labels[:-1] %} {% endfor %} {% for row_idx in range(self_similarity.n_themes) %} {% for col_idx in range(self_similarity.n_themes - 1) %} {% if col_idx < row_idx %} {% else %} {% endif %} {% endfor %} {% endfor %}
{{ label }}
{{ self_similarity.short_labels[row_idx] }}: {{ self_similarity.themes[row_idx][:30] }}{% if self_similarity.themes[row_idx]|length > 30 %}...{% endif %}
Legend: ≥0.7 0.5-0.7 0.4-0.5 0.25-0.4 <0.25
{% endif %}

Codes

{% if result.codes %} {% for code in result.codes %} {% set code_obj = code if code.slug is defined else code %}
{{ code_obj.name or code_obj.get('name', '') }} {{ code_obj.slug or code_obj.get('slug', '') }}
{{ code_obj.description or code_obj.get('description', '') }}
{% set quotes = code_obj.resolved_quotes or code_obj.get('resolved_quotes') or code_obj.quotes or code_obj.get('quotes') or [] %} {% if quotes %}
Supporting Quotes ({{ quotes|length }})
{% for quote in quotes %}
{% if quote.text is defined %}{{ quote.text }}{% elif quote.get is defined %}{{ quote.get('text', quote) }}{% else %}{{ quote }}{% endif %}
{% endfor %}
{% else %}
No quotes available for this code.
{% endif %}
{% endfor %} {% else %}

No codes available.

{% endif %}
{% if verification_data %}

Quote Verification

Shows how quotes were matched against source documents using BM25 lexical search and embedding similarity. {% if verification_data.flagged > 0 %} {{ verification_data.flagged }} quotes flagged for review. {% endif %}

{% for match in verification_data.matches %} {% endfor %}
Quote Code BM25 Similarity LLM
"{{ match.quote[:80] }}{% if match.quote|length > 80 %}...{% endif %}"
{% if match.code_name %} {{ match.code_name }} {% else %} - {% endif %} {{ "%.1f"|format(match.bm25_score) }} {% if match.calibrated_similarity is not none %} {{ "%.2f"|format(match.calibrated_similarity) }} {% else %} {{ "%.2f"|format(match.cosine_similarity) }} {% endif %} {% if match.llm_is_contained is true %} OK {% elif match.llm_is_contained is false %} Not Found {% else %} - {% endif %}
Full quote:
"{{ match.quote }}"
{% if match.span_text %}
Found in context:
...{{ match.context_before }}{{ match.span_text }}{{ match.context_after }}...
{% endif %}
BM25: {{ "%.1f"|format(match.bm25_score) }}
Ratio: {{ "%.1f"|format(match.bm25_ratio) }}
{% if match.calibrated_similarity is not none %}
Calibrated: {{ "%.3f"|format(match.calibrated_similarity) }}
{% endif %}
Cosine: {{ "%.3f"|format(match.cosine_similarity) }}
{% if match.llm_explanation %}
LLM explanation: {{ match.llm_explanation }}
{% endif %} {% if match.source_doc %}
Source: {{ match.source_doc }}
{% endif %}
{% endif %}

Run Configuration

{% if pipeline.config.export_metadata and pipeline.config.export_metadata.command %}
CLI Command:
{{ pipeline.config.export_metadata.command }}
{% endif %}
Pipeline
{{ pipeline.name }}
{% if pipeline.config.model_name %}
Model
{{ pipeline.config.model_name }}
{% endif %} {% if pipeline.config.sample_n %}
Sample
{{ pipeline.config.sample_n }} documents (randomly sampled)
{% endif %} {% if pipeline.config.head_n %}
Head
{{ pipeline.config.head_n }} documents (first N)
{% endif %} {% if pipeline.config.seed %}
Seed
{{ pipeline.config.seed }}
{% endif %}
Documents
{{ pipeline.config.document_paths|length }} files{% if pipeline.config.input_source %} from {{ pipeline.config.input_source }}{% endif %}
{% include '_offcanvas.html' %} {% include '_alpine_components.html' %}