mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-19 00:14:40 +00:00
feat: redesign advanced settings panel as settings rows with dividers
Group eyebrow headers with short live/re-ingest tags, lighter field labels, hairline dividers between rows, compact right-aligned controls, and hide the single-option Retriever select.
This commit is contained in:
1 parent
e18886b4f1
commit
f2e6967ec9
2 files changed
+296
-253
No files matched your search
@@ -137,6 +137,7 @@
|
|||||||
"retrieval": {
|
"retrieval": {
|
||||||
"title": "Retrieval",
|
"title": "Retrieval",
|
||||||
"note": "These changes take effect immediately, no re-ingest needed.",
|
"note": "These changes take effect immediately, no re-ingest needed.",
|
||||||
|
"tag": "live · no re-ingest",
|
||||||
"chunks": "Chunks to retrieve (top-k)",
|
"chunks": "Chunks to retrieve (top-k)",
|
||||||
"scoreThreshold": "Score threshold",
|
"scoreThreshold": "Score threshold",
|
||||||
"scoreThresholdPlaceholder": "None",
|
"scoreThresholdPlaceholder": "None",
|
||||||
@@ -165,6 +166,7 @@
|
|||||||
"chunking": {
|
"chunking": {
|
||||||
"title": "Chunking",
|
"title": "Chunking",
|
||||||
"note": "Ingest-time settings. Changing these requires re-ingesting the source.",
|
"note": "Ingest-time settings. Changing these requires re-ingesting the source.",
|
||||||
|
"tag": "re-ingest to apply",
|
||||||
"strategy": "Chunking strategy",
|
"strategy": "Chunking strategy",
|
||||||
"strategies": {
|
"strategies": {
|
||||||
"classic_chunk": "Classic",
|
"classic_chunk": "Classic",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useMemo, useState } from 'react';
|
import { type ReactNode, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
import { Button } from '../../components/ui/button';
|
import { Button } from '../../components/ui/button';
|
||||||
import { Input } from '../../components/ui/input';
|
import { Input } from '../../components/ui/input';
|
||||||
import { Label } from '../../components/ui/label';
|
import { Label } from '../../components/ui/label';
|
||||||
@@ -83,6 +85,64 @@ const CHUNKING_STRATEGIES: ChunkingStrategy[] = [
|
|||||||
'parent_child',
|
'parent_child',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group eyebrow: an uppercase, tracked title with a normal-weight muted ` · tag`
|
||||||
|
* suffix. Reads as more prominent than the individual field labels below it.
|
||||||
|
*/
|
||||||
|
function GroupHeader({ title, tag }: { title: string; tag: string }) {
|
||||||
|
return (
|
||||||
|
<h4 className="text-foreground text-xs font-semibold tracking-wider uppercase">
|
||||||
|
{title}
|
||||||
|
<span className="text-muted-foreground font-normal normal-case">
|
||||||
|
{' · '}
|
||||||
|
{tag}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One settings row: a left block (medium-weight label plus optional muted
|
||||||
|
* description) and a right block holding the control. `alignStart` top-aligns
|
||||||
|
* the row for controls paired with a multi-line description; otherwise both
|
||||||
|
* sides are vertically centered.
|
||||||
|
*/
|
||||||
|
function SettingRow({
|
||||||
|
label,
|
||||||
|
htmlFor,
|
||||||
|
description,
|
||||||
|
alignStart = false,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
label: string;
|
||||||
|
htmlFor?: string;
|
||||||
|
description?: ReactNode;
|
||||||
|
alignStart?: boolean;
|
||||||
|
children: ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex flex-row justify-between gap-4 py-3 first:pt-0 last:pb-0',
|
||||||
|
alignStart ? 'items-start' : 'items-center',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex min-w-0 flex-1 flex-col gap-0.5">
|
||||||
|
<Label
|
||||||
|
htmlFor={htmlFor}
|
||||||
|
className="text-foreground text-sm font-medium"
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Label>
|
||||||
|
{description ? (
|
||||||
|
<p className="text-muted-foreground text-xs">{description}</p>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
<div className="shrink-0">{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hydrate the form value from a stored (possibly partial/absent) SourceConfig,
|
* Hydrate the form value from a stored (possibly partial/absent) SourceConfig,
|
||||||
* filling every missing field with the documented default. Lenient on read so a
|
* filling every missing field with the documented default. Lenient on read so a
|
||||||
@@ -238,277 +298,258 @@ export default function RetrievalOptions({
|
|||||||
const body = (
|
const body = (
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
{/* Retrieval group (live) */}
|
{/* Retrieval group (live) */}
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-3">
|
||||||
<div>
|
<GroupHeader title={tr('retrieval.title')} tag={tr('retrieval.tag')} />
|
||||||
<h4 className="text-foreground text-sm font-semibold">
|
|
||||||
{tr('retrieval.title')}
|
|
||||||
</h4>
|
|
||||||
<p className="text-muted-foreground mt-0.5 text-xs">
|
|
||||||
{tr('retrieval.note')}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Input
|
<div className="divide-border/50 divide-y">
|
||||||
type="number"
|
<SettingRow label={tr('retrieval.chunks')} htmlFor="retrieval-chunks">
|
||||||
min={1}
|
<Input
|
||||||
label={tr('retrieval.chunks')}
|
id="retrieval-chunks"
|
||||||
value={String(value.retrieval.chunks)}
|
type="number"
|
||||||
disabled={disabled}
|
min={1}
|
||||||
labelBgClassName="bg-card"
|
className="w-24 text-right"
|
||||||
onChange={(e) =>
|
value={String(value.retrieval.chunks)}
|
||||||
setRetrieval({ chunks: Math.max(1, Number(e.target.value) || 1) })
|
disabled={disabled}
|
||||||
}
|
onChange={(e) =>
|
||||||
/>
|
setRetrieval({
|
||||||
|
chunks: Math.max(1, Number(e.target.value) || 1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</SettingRow>
|
||||||
|
|
||||||
<div className="flex flex-col gap-1.5">
|
<SettingRow
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
step="0.01"
|
|
||||||
label={tr('retrieval.scoreThreshold')}
|
label={tr('retrieval.scoreThreshold')}
|
||||||
value={
|
htmlFor="retrieval-score-threshold"
|
||||||
value.retrieval.score_threshold === null
|
description={tr('retrieval.scoreThresholdHint')}
|
||||||
? ''
|
alignStart
|
||||||
: String(value.retrieval.score_threshold)
|
|
||||||
}
|
|
||||||
disabled={disabled}
|
|
||||||
labelBgClassName="bg-card"
|
|
||||||
placeholder={tr('retrieval.scoreThresholdPlaceholder')}
|
|
||||||
onChange={(e) => {
|
|
||||||
const raw = e.target.value;
|
|
||||||
setRetrieval({
|
|
||||||
score_threshold: raw === '' ? null : Number(raw),
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<p className="text-muted-foreground text-xs">
|
|
||||||
{tr('retrieval.scoreThresholdHint')}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-row items-center justify-between gap-3">
|
|
||||||
<Label htmlFor="retrieval-rephrase" className="text-foreground">
|
|
||||||
{tr('retrieval.rephraseQuery')}
|
|
||||||
</Label>
|
|
||||||
<Switch
|
|
||||||
id="retrieval-rephrase"
|
|
||||||
checked={value.retrieval.rephrase_query}
|
|
||||||
disabled={disabled}
|
|
||||||
onCheckedChange={(checked) =>
|
|
||||||
setRetrieval({ rephrase_query: checked })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-1.5">
|
|
||||||
<Label htmlFor="retrieval-retriever" className="text-foreground">
|
|
||||||
{tr('retrieval.retriever')}
|
|
||||||
</Label>
|
|
||||||
<Select value="classic" disabled>
|
|
||||||
<SelectTrigger
|
|
||||||
id="retrieval-retriever"
|
|
||||||
className="w-full rounded-md"
|
|
||||||
size="lg"
|
|
||||||
>
|
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="classic">
|
|
||||||
{tr('retrieval.retrievers.classic')}
|
|
||||||
</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-1.5">
|
|
||||||
<Label htmlFor="retrieval-exposure" className="text-foreground">
|
|
||||||
{tr('retrieval.exposure')}
|
|
||||||
</Label>
|
|
||||||
<Select
|
|
||||||
value={value.retrieval.exposure}
|
|
||||||
disabled={disabled}
|
|
||||||
onValueChange={(v) =>
|
|
||||||
setRetrieval({ exposure: v as RetrievalExposure })
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<SelectTrigger
|
<Input
|
||||||
id="retrieval-exposure"
|
id="retrieval-score-threshold"
|
||||||
className="w-full rounded-md"
|
type="number"
|
||||||
size="lg"
|
step="0.01"
|
||||||
>
|
className="w-24 text-right"
|
||||||
<SelectValue />
|
value={
|
||||||
</SelectTrigger>
|
value.retrieval.score_threshold === null
|
||||||
<SelectContent>
|
? ''
|
||||||
<SelectItem value="prefetch">
|
: String(value.retrieval.score_threshold)
|
||||||
{tr('retrieval.exposures.prefetch')}
|
}
|
||||||
</SelectItem>
|
disabled={disabled}
|
||||||
<SelectItem value="agentic_tool">
|
placeholder={tr('retrieval.scoreThresholdPlaceholder')}
|
||||||
{tr('retrieval.exposures.agentic_tool')}
|
onChange={(e) => {
|
||||||
</SelectItem>
|
const raw = e.target.value;
|
||||||
</SelectContent>
|
setRetrieval({
|
||||||
</Select>
|
score_threshold: raw === '' ? null : Number(raw),
|
||||||
<p className="text-muted-foreground text-xs">
|
});
|
||||||
{tr('retrieval.exposureHint')}
|
}}
|
||||||
</p>
|
/>
|
||||||
</div>
|
</SettingRow>
|
||||||
|
|
||||||
{/* Prescreen sub-group */}
|
<SettingRow
|
||||||
<div className="flex flex-col gap-3">
|
label={tr('retrieval.rephraseQuery')}
|
||||||
<div className="flex flex-row items-center justify-between gap-3">
|
htmlFor="retrieval-rephrase"
|
||||||
<Label htmlFor="retrieval-prescreen" className="text-foreground">
|
>
|
||||||
{tr('prescreen.enable')}
|
<Switch
|
||||||
</Label>
|
id="retrieval-rephrase"
|
||||||
|
checked={value.retrieval.rephrase_query}
|
||||||
|
disabled={disabled}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
setRetrieval({ rephrase_query: checked })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</SettingRow>
|
||||||
|
|
||||||
|
<SettingRow
|
||||||
|
label={tr('retrieval.exposure')}
|
||||||
|
htmlFor="retrieval-exposure"
|
||||||
|
description={tr('retrieval.exposureHint')}
|
||||||
|
alignStart
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
value={value.retrieval.exposure}
|
||||||
|
disabled={disabled}
|
||||||
|
onValueChange={(v) =>
|
||||||
|
setRetrieval({ exposure: v as RetrievalExposure })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SelectTrigger
|
||||||
|
id="retrieval-exposure"
|
||||||
|
className="w-52 rounded-md"
|
||||||
|
size="lg"
|
||||||
|
>
|
||||||
|
<SelectValue />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="prefetch">
|
||||||
|
{tr('retrieval.exposures.prefetch')}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="agentic_tool">
|
||||||
|
{tr('retrieval.exposures.agentic_tool')}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</SettingRow>
|
||||||
|
|
||||||
|
<SettingRow
|
||||||
|
label={tr('prescreen.enable')}
|
||||||
|
htmlFor="retrieval-prescreen"
|
||||||
|
description={tr('prescreen.warning')}
|
||||||
|
alignStart
|
||||||
|
>
|
||||||
<Switch
|
<Switch
|
||||||
id="retrieval-prescreen"
|
id="retrieval-prescreen"
|
||||||
checked={value.retrieval.prescreen.enabled}
|
checked={value.retrieval.prescreen.enabled}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onCheckedChange={(checked) => setPrescreen({ enabled: checked })}
|
onCheckedChange={(checked) => setPrescreen({ enabled: checked })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</SettingRow>
|
||||||
<p className="text-muted-foreground text-xs">
|
|
||||||
{tr('prescreen.warning')}
|
|
||||||
</p>
|
|
||||||
{value.retrieval.prescreen.enabled && (
|
|
||||||
<div className="border-border flex flex-col gap-4 rounded-lg border p-4">
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
min={value.retrieval.chunks}
|
|
||||||
label={tr('prescreen.candidateK')}
|
|
||||||
value={String(value.retrieval.prescreen.candidate_k)}
|
|
||||||
disabled={disabled}
|
|
||||||
labelBgClassName="bg-card"
|
|
||||||
onChange={(e) =>
|
|
||||||
setPrescreen({
|
|
||||||
candidate_k: Math.max(
|
|
||||||
value.retrieval.chunks,
|
|
||||||
Number(e.target.value) || value.retrieval.chunks,
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
min={1}
|
|
||||||
label={tr('prescreen.maxKeep')}
|
|
||||||
value={String(value.retrieval.prescreen.max_keep)}
|
|
||||||
disabled={disabled}
|
|
||||||
labelBgClassName="bg-card"
|
|
||||||
onChange={(e) =>
|
|
||||||
setPrescreen({
|
|
||||||
max_keep: Math.min(
|
|
||||||
value.retrieval.prescreen.candidate_k,
|
|
||||||
Math.max(1, Number(e.target.value) || 1),
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
min={1}
|
|
||||||
label={tr('prescreen.batchSize')}
|
|
||||||
value={String(value.retrieval.prescreen.batch_size)}
|
|
||||||
disabled={disabled}
|
|
||||||
labelBgClassName="bg-card"
|
|
||||||
onChange={(e) =>
|
|
||||||
setPrescreen({
|
|
||||||
batch_size: Math.max(1, Number(e.target.value) || 1),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
type="text"
|
|
||||||
label={tr('prescreen.model')}
|
|
||||||
value={value.retrieval.prescreen.model ?? ''}
|
|
||||||
disabled={disabled}
|
|
||||||
labelBgClassName="bg-card"
|
|
||||||
placeholder={tr('prescreen.modelPlaceholder')}
|
|
||||||
onChange={(e) =>
|
|
||||||
setPrescreen({ model: e.target.value || null })
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Prescreen expanded inputs (kept as floating-label cards) */}
|
||||||
|
{value.retrieval.prescreen.enabled && (
|
||||||
|
<div className="border-border ml-4 flex flex-col gap-4 rounded-lg border p-4">
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
min={value.retrieval.chunks}
|
||||||
|
label={tr('prescreen.candidateK')}
|
||||||
|
value={String(value.retrieval.prescreen.candidate_k)}
|
||||||
|
disabled={disabled}
|
||||||
|
labelBgClassName="bg-card"
|
||||||
|
onChange={(e) =>
|
||||||
|
setPrescreen({
|
||||||
|
candidate_k: Math.max(
|
||||||
|
value.retrieval.chunks,
|
||||||
|
Number(e.target.value) || value.retrieval.chunks,
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
label={tr('prescreen.maxKeep')}
|
||||||
|
value={String(value.retrieval.prescreen.max_keep)}
|
||||||
|
disabled={disabled}
|
||||||
|
labelBgClassName="bg-card"
|
||||||
|
onChange={(e) =>
|
||||||
|
setPrescreen({
|
||||||
|
max_keep: Math.min(
|
||||||
|
value.retrieval.prescreen.candidate_k,
|
||||||
|
Math.max(1, Number(e.target.value) || 1),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
label={tr('prescreen.batchSize')}
|
||||||
|
value={String(value.retrieval.prescreen.batch_size)}
|
||||||
|
disabled={disabled}
|
||||||
|
labelBgClassName="bg-card"
|
||||||
|
onChange={(e) =>
|
||||||
|
setPrescreen({
|
||||||
|
batch_size: Math.max(1, Number(e.target.value) || 1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
label={tr('prescreen.model')}
|
||||||
|
value={value.retrieval.prescreen.model ?? ''}
|
||||||
|
disabled={disabled}
|
||||||
|
labelBgClassName="bg-card"
|
||||||
|
placeholder={tr('prescreen.modelPlaceholder')}
|
||||||
|
onChange={(e) => setPrescreen({ model: e.target.value || null })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr className="border-border/60" />
|
|
||||||
|
|
||||||
{/* Chunking group (re-ingest required) */}
|
{/* Chunking group (re-ingest required) */}
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-3">
|
||||||
<div>
|
<GroupHeader title={tr('chunking.title')} tag={tr('chunking.tag')} />
|
||||||
<h4 className="text-foreground text-sm font-semibold">
|
|
||||||
{tr('chunking.title')}
|
|
||||||
</h4>
|
|
||||||
<p className="text-muted-foreground mt-0.5 text-xs">
|
|
||||||
{tr('chunking.note')}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-1.5">
|
<div className="divide-border/50 divide-y">
|
||||||
<Label htmlFor="chunking-strategy" className="text-foreground">
|
<SettingRow
|
||||||
{tr('chunking.strategy')}
|
label={tr('chunking.strategy')}
|
||||||
</Label>
|
htmlFor="chunking-strategy"
|
||||||
<Select
|
|
||||||
value={value.chunking.strategy}
|
|
||||||
disabled={disabled}
|
|
||||||
onValueChange={(v) =>
|
|
||||||
setChunking({ strategy: v as ChunkingStrategy })
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<SelectTrigger
|
<Select
|
||||||
id="chunking-strategy"
|
value={value.chunking.strategy}
|
||||||
className="w-full rounded-md"
|
disabled={disabled}
|
||||||
size="lg"
|
onValueChange={(v) =>
|
||||||
|
setChunking({ strategy: v as ChunkingStrategy })
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<SelectValue />
|
<SelectTrigger
|
||||||
</SelectTrigger>
|
id="chunking-strategy"
|
||||||
<SelectContent>
|
className="w-52 rounded-md"
|
||||||
{strategyOptions.map((opt) => (
|
size="lg"
|
||||||
<SelectItem key={opt.value} value={opt.value}>
|
>
|
||||||
{opt.label}
|
<SelectValue />
|
||||||
</SelectItem>
|
</SelectTrigger>
|
||||||
))}
|
<SelectContent>
|
||||||
</SelectContent>
|
{strategyOptions.map((opt) => (
|
||||||
</Select>
|
<SelectItem key={opt.value} value={opt.value}>
|
||||||
</div>
|
{opt.label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</SettingRow>
|
||||||
|
|
||||||
<Input
|
<SettingRow
|
||||||
type="number"
|
label={tr('chunking.maxTokens')}
|
||||||
min={1}
|
htmlFor="chunking-max-tokens"
|
||||||
label={tr('chunking.maxTokens')}
|
>
|
||||||
value={String(value.chunking.max_tokens)}
|
<Input
|
||||||
disabled={disabled}
|
id="chunking-max-tokens"
|
||||||
labelBgClassName="bg-card"
|
type="number"
|
||||||
onChange={(e) =>
|
min={1}
|
||||||
setChunking({
|
className="w-24 text-right"
|
||||||
max_tokens: Math.max(1, Number(e.target.value) || 1),
|
value={String(value.chunking.max_tokens)}
|
||||||
})
|
disabled={disabled}
|
||||||
}
|
onChange={(e) =>
|
||||||
/>
|
setChunking({
|
||||||
<Input
|
max_tokens: Math.max(1, Number(e.target.value) || 1),
|
||||||
type="number"
|
})
|
||||||
min={0}
|
}
|
||||||
label={tr('chunking.minTokens')}
|
/>
|
||||||
value={String(value.chunking.min_tokens)}
|
</SettingRow>
|
||||||
disabled={disabled}
|
|
||||||
labelBgClassName="bg-card"
|
<SettingRow
|
||||||
onChange={(e) =>
|
label={tr('chunking.minTokens')}
|
||||||
setChunking({
|
htmlFor="chunking-min-tokens"
|
||||||
min_tokens: Math.max(0, Number(e.target.value) || 0),
|
>
|
||||||
})
|
<Input
|
||||||
}
|
id="chunking-min-tokens"
|
||||||
/>
|
type="number"
|
||||||
<div className="flex flex-row items-center justify-between gap-3">
|
min={0}
|
||||||
<Label htmlFor="chunking-dup-headers" className="text-foreground">
|
className="w-24 text-right"
|
||||||
{tr('chunking.duplicateHeaders')}
|
value={String(value.chunking.min_tokens)}
|
||||||
</Label>
|
disabled={disabled}
|
||||||
<Switch
|
onChange={(e) =>
|
||||||
id="chunking-dup-headers"
|
setChunking({
|
||||||
checked={value.chunking.duplicate_headers}
|
min_tokens: Math.max(0, Number(e.target.value) || 0),
|
||||||
disabled={disabled}
|
})
|
||||||
onCheckedChange={(checked) =>
|
}
|
||||||
setChunking({ duplicate_headers: checked })
|
/>
|
||||||
}
|
</SettingRow>
|
||||||
/>
|
|
||||||
|
<SettingRow
|
||||||
|
label={tr('chunking.duplicateHeaders')}
|
||||||
|
htmlFor="chunking-dup-headers"
|
||||||
|
>
|
||||||
|
<Switch
|
||||||
|
id="chunking-dup-headers"
|
||||||
|
checked={value.chunking.duplicate_headers}
|
||||||
|
disabled={disabled}
|
||||||
|
onCheckedChange={(checked) =>
|
||||||
|
setChunking({ duplicate_headers: checked })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</SettingRow>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user