---
title: Research
description: A research copilot with its process, numbered citations, and an evidence rail.
category: TemplateAi
status: beta
since: 0.6.0
tags: [template, ai, research, citation, rag]
syncStatus: reviewed
verified: false
---

## Usage

### Cited research report
:::TuffDemoWrapper{demo="TemplateResearchDemo" code-lang="vue" description="Click a numbered citation to find and highlight its entry in the evidence rail. Sample figures."}
---
code: |
  <script setup lang="ts">
  import { useStickToBottom } from '@talex-touch/tuffex/conversation-stream'
  import { nextTick, ref } from 'vue'
  import TemplateFrame from './TemplateFrame.vue'

  const scroller = ref<HTMLElement | null>(null)
  // The answer column follows streamed content until the reader scrolls up
  const stick = useStickToBottom(scroller)

  // A citation switches the rail's tab and scrolls only the rail's own scroller
  function onCite(source: AiSourceItem) {
    railTab.value = chunkOf(source) ? 'chunks' : 'sources'
    nextTick(() => railScroller().scrollTo({ top: offsetOf(source), behavior: 'smooth' }))
  }
  </script>

  <template>
    <TemplateFrame title="Research" @enter="run">
      <template #default="{ width }">
        <div class="research">
          <main ref="scroller" class="research__main" @scroll="stick.handleScroll" @wheel="stick.handleWheel">
            <TxChainOfThought :steps="steps" :streaming="researching" :default-open="false" label="Research process" />

            <!-- Citations are components, so they live in a plain paragraph revealed token by token -->
            <p class="research__answer">
              <template v-for="token in shownTokens" :key="token.id">
                <TxInlineCitation v-if="token.cite" :source="token.cite" :label="token.number" @open="onCite" />
                <span v-else>{{ token.text }}</span>
              </template>
            </p>

            <!-- The table renders through v-html, so it carries no links -->
            <TxStreamMarkdown :content="table" :streaming="writingTable" />
            <TxInsightCards v-model:active-index="page" :pages="insights" @follow-up="ask" />
            <TxRecommendationCard v-model="choice" v-model:accepted="accepted" :options="options" @accept="saveNote" />
            <TxSuggestionChips :suggestions="followUps" layout="list" @select="ask" />

            <TxAiConversation :messages="thread">
              <template #default="{ message }">
                <TxReasoningDisclosure :text="reasoningOf(message)" label="Reasoning" />
                <TxStreamMarkdown :content="answerOf(message)" :streaming="isStreaming(message)" />
              </template>
            </TxAiConversation>
          </main>

          <aside v-if="width >= 640" class="research__rail">
            <TxTabs v-model="railTab" placement="top" borderless>
              <TxTabItem name="sources">
                <template #name>Sources</template>
                <template #default>
                  <TxSources :sources="sources" default-open @open="hostOpens" />
                </template>
              </TxTabItem>
              <TxTabItem name="chunks">
                <template #name>Chunks</template>
                <template #default>
                  <TxContextCards :chunks="chunks" title="Matched chunks" :total="32" @open="hostOpens" />
                </template>
              </TxTabItem>
              <TxTabItem name="notes">
                <template #name>Notes</template>
                <template #default>
                  <TxMarkdownView :content="note" />
                </template>
              </TxTabItem>
            </TxTabs>
          </aside>
        </div>
      </template>
    </TemplateFrame>
  </template>
---
:::

## Overview

A research copilot with traceable conclusions: its process, a cited conclusion, a comparison table, insights, and a recommendation arrive in turn.

- It researches once in view and takes about 10 seconds; Reset or Research again replays it, and reduced motion renders the finished answer at once.
- A numbered citation switches the rail to the matching tab and scrolls only inside it: a citation with a retrieved chunk lands on the chunk, the rest on the source.
- Clicking a source or a chunk's origin only shows "The host would open …"; the page never navigates.
- The recommendation card switches between alternatives; Save plan writes the draft into the Notes tab.
- A follow-up appends a question and an answer with an expandable reasoning note; the answer column follows streamed content until you scroll up.
- In the docs column (640–959px) the rail uses tabs, and ≥ 1200px gives the insights their own column; narrow (< 640px) hides the rail and stacks the sources under the conclusion.

## Customization

- To wire a real service, map research steps onto TxChainOfThought's `steps` (one `active` at a time), append the conclusion token by token, and hand tables to TxStreamMarkdown.
- Clickable citations cannot live in markdown (TxStreamMarkdown renders through `v-html`): render the cited paragraph on its own, and keep links out of the markdown too.
- Scroll the rail with its scroller's `scrollTo`, not `scrollIntoView`, which drags the whole page.
- Label unmeasured claims about third-party products as qualitative or sample data; give the recommendation's confidence a text label.

## Related components

| Region | Components | Role |
|---|---|---|
| Header | [TxWorkingIndicator](/docs/dev/components/working-indicator), [TxStatusBadge](/docs/dev/components/status-badge) | Phase, elapsed time, and done state |
| Research process | [TxChainOfThought](/docs/dev/components/chain-of-thought) | Four steps that fold when done |
| Conclusion | [TxInlineCitation](/docs/dev/components/inline-citation) | Revealed conclusion with numbered citations |
| Comparison | [TxStreamMarkdown](/docs/dev/components/stream-markdown) | Streamed comparison, no links |
| Insights and recommendation | [TxInsightCards](/docs/dev/components/insight-cards), [TxRecommendationCard](/docs/dev/components/recommendation-card) | Pageable insights and a recommendation |
| Follow-ups | [TxSuggestionChips](/docs/dev/components/suggestion-chips), [TxAiConversation](/docs/dev/components/ai-elements), [TxReasoningDisclosure](/docs/dev/components/reasoning-disclosure), [TxTypingIndicator](/docs/dev/components/typing-indicator) | Follow-ups and a Q&A thread |
| Evidence rail | [TxTabs](/docs/dev/components/tabs), [TxSources](/docs/dev/components/sources), [TxContextCards](/docs/dev/components/context-cards), [TxSignalMeter](/docs/dev/components/signal-meter), [TxSkeleton](/docs/dev/components/skeleton) | Sources, Chunks, and Notes tabs |
| Notes | [TxMarkdownView](/docs/dev/components/markdown-view), [TxMessageActions](/docs/dev/components/message-actions) | Adopted plan draft, with copy |
| Input | [TxPromptBar](/docs/dev/components/prompt-bar) | Follow-up input, commands, and modes |
