Knowledge Chat: surface LangSmith trace link when tracing enabled (reads /rag/config)
This commit is contained in:
@@ -40,6 +40,7 @@ export function KnowledgeChatView({ onGpuActivity }: Props = {}) {
|
||||
const [catalogDocs, setCatalogDocs] = useState<number | null>(null)
|
||||
const [showArch, setShowArch] = useState(true)
|
||||
const [activeStage, setActiveStage] = useState<number | null>(null)
|
||||
const [traceCfg, setTraceCfg] = useState<{ tracing: boolean; project: string; smith_url: string } | null>(null)
|
||||
const bottomRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const loadMeta = useCallback(async () => {
|
||||
@@ -77,6 +78,13 @@ export function KnowledgeChatView({ onGpuActivity }: Props = {}) {
|
||||
loadCatalog()
|
||||
}, [loadMeta, loadCatalog])
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/rag/config')
|
||||
.then((r) => (r.ok ? r.json() : null))
|
||||
.then((c) => { if (c) setTraceCfg(c) })
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
bottomRef.current?.scrollIntoView({ behavior: 'smooth' })
|
||||
}, [messages, loading])
|
||||
@@ -351,6 +359,17 @@ export function KnowledgeChatView({ onGpuActivity }: Props = {}) {
|
||||
<StatusPill ok={health.llm} label="LLM" />
|
||||
</>
|
||||
)}
|
||||
{traceCfg?.tracing && (
|
||||
<a
|
||||
href={traceCfg.smith_url}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title={`LangSmith project: ${traceCfg.project}`}
|
||||
className="inline-flex items-center gap-1 rounded border border-emerald-400/50 bg-emerald-500/15 px-2 py-1 text-[10px] font-medium text-emerald-300 hover:bg-emerald-500/25"
|
||||
>
|
||||
<Workflow className="h-3.5 w-3.5" /> LangSmith ↗
|
||||
</a>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowArch((v) => !v)}
|
||||
@@ -369,7 +388,7 @@ export function KnowledgeChatView({ onGpuActivity }: Props = {}) {
|
||||
|
||||
{showArch && (
|
||||
<div className="shrink-0 border-b border-border bg-surface-overlay/20 px-4 py-3">
|
||||
<RagFlow loading={loading} ingesting={ingesting} activeStage={activeStage} />
|
||||
<RagFlow loading={loading} ingesting={ingesting} activeStage={activeStage} smithUrl={traceCfg?.tracing ? traceCfg.smith_url : null} project={traceCfg?.project} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -565,7 +584,7 @@ const QUERY_STAGES = [
|
||||
|
||||
const STAGE_LABEL = ['Question', 'Embed', 'Retrieve', 'Context', 'LLM', 'Answer']
|
||||
|
||||
function RagFlow({ loading, ingesting, activeStage }: { loading: boolean; ingesting: boolean; activeStage: number | null }) {
|
||||
function RagFlow({ loading, ingesting, activeStage, smithUrl, project }: { loading: boolean; ingesting: boolean; activeStage: number | null; smithUrl?: string | null; project?: string }) {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-wrap items-center gap-2 text-[9px] font-semibold uppercase tracking-wider text-foreground-faint">
|
||||
@@ -574,6 +593,9 @@ function RagFlow({ loading, ingesting, activeStage }: { loading: boolean; ingest
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-emerald-400" /> orchestrated by LangChain
|
||||
</span>
|
||||
<span className="rounded bg-docker/15 px-1.5 py-0.5 font-mono text-[8px] normal-case text-docker">ChromaDB · Docling · sentence-transformers</span>
|
||||
{smithUrl && (
|
||||
<a href={smithUrl} target="_blank" rel="noreferrer" title={project ? `LangSmith project: ${project}` : 'LangSmith'} className="inline-flex items-center gap-1 rounded-md border border-emerald-400/40 bg-emerald-500/10 px-1.5 py-0.5 font-mono text-[8px] normal-case text-emerald-300 hover:bg-emerald-500/20">LangSmith traces ↗</a>
|
||||
)}
|
||||
{activeStage != null && (
|
||||
<span className="ml-auto flex items-center gap-1 normal-case text-docker">
|
||||
<span className="h-1.5 w-1.5 animate-ping rounded-full bg-docker" /> {STAGE_LABEL[activeStage] || 'working'}…
|
||||
|
||||
Reference in New Issue
Block a user