import { useState } from "react"; import { api } from "../api"; import type { KeywordAnalysisResponse } from "../types"; import { useApiCall } from "../hooks/useApiCall"; import ScoreBar from "./ScoreBar"; import StatusMessage from "./StatusMessage"; export default function KeywordAnalysis() { const [keyword, setKeyword] = useState(""); const [topK, setTopK] = useState(5); const [threshold, setThreshold] = useState(0.4); const { data: analysis, loading, error, run } = useApiCall(); async function handleAnalyze() { if (!keyword.trim()) return; await run(() => api.analyzeKeyword({ keyword, top_k: topK, cluster_threshold: threshold })); } return (

Keyword Analysis

Find all occurrences of a keyword, cluster them by contextual meaning, and discover semantically similar passages for each meaning.

setKeyword(e.target.value)} placeholder="e.g. pizza" onKeyDown={(e) => e.key === "Enter" && handleAnalyze()} />
setTopK(+e.target.value)} min={1} max={50} />
setThreshold(+e.target.value)} min={0.1} max={1} step={0.05} />
{error && } {analysis && (

"{analysis.keyword}" — {analysis.total_occurrences} occurrence(s),{" "} {analysis.meaning_clusters.length} meaning cluster(s)

{analysis.meaning_clusters.map((cluster) => (
Cluster {cluster.cluster_id}{" "} {cluster.size} occurrence(s)
Contexts:
{cluster.contexts.map((ctx, i) => (
{ctx.doc_id} {ctx.text.slice(0, 200)}...
))}
Similar passages:
{cluster.similar_passages.map((sp) => (
{sp.doc_id} {sp.text.slice(0, 150)}...
))}
))}
)}
); }