Files
LangBot/web/src/app/home/components/models-dialog/components/ExtraArgsEditor.tsx
T
huanghuoguoguo 323481d69b Feat/rerank model (#2137)
* feat(provider): add rerank model management as a core model type

* feat(provider): add rerank support to existing requesters and new rerank providers

* feat(web): add rerank model management UI and pipeline config

* fix(provider): correct rerank support_type after verification

- Add rerank to OpenRouter (confirmed /api/v1/rerank endpoint)
- Remove rerank from Ollama (no native support, PR #7219 unmerged)
- Remove rerank from JiekouAI (no rerank docs found, URL path mismatch)

* fix(provider): remove alru_cache from model getters and add rerank param hints

* fix: resolve lint errors

- Remove unused alru_cache import from modelmgr.py
- Remove unused error_message variable in invoke_rerank
- Fix prettier formatting in frontend files

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: remove unused exception variable

- Change `except Exception as e:` to `except Exception:` since e is not used
- Fix prettier formatting in ProviderCard.tsx

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: apply ruff format

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(template): add rerank config fields to default pipeline config

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: remove PR.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(ui): remove duplicate rerank model form in AddModelPopover

The form was being rendered twice: once in TabsContent manual mode
and again in a separate conditional block for rerank tab.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 23:32:36 +08:00

140 lines
4.1 KiB
TypeScript

import { Plus, X, HelpCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { useTranslation } from 'react-i18next';
import { ExtraArg, ModelType } from '../types';
interface ExtraArgsEditorProps {
args: ExtraArg[];
onChange: (args: ExtraArg[]) => void;
disabled?: boolean;
modelType?: ModelType;
}
export default function ExtraArgsEditor({
args,
onChange,
disabled = false,
modelType,
}: ExtraArgsEditorProps) {
const { t } = useTranslation();
const handleAdd = () => {
onChange([...args, { key: '', type: 'string', value: '' }]);
};
const handleRemove = (index: number) => {
onChange(args.filter((_, i) => i !== index));
};
const handleUpdate = (
index: number,
field: keyof ExtraArg,
value: string,
) => {
const newArgs = [...args];
newArgs[index] = { ...newArgs[index], [field]: value };
onChange(newArgs);
};
return (
<div className="space-y-2">
<div className="flex items-center justify-between">
<div className="flex items-center gap-1">
<Label>{t('models.extraParameters')}</Label>
{modelType === 'rerank' && (
<Tooltip>
<TooltipTrigger asChild>
<HelpCircle className="h-4 w-4 text-muted-foreground cursor-help" />
</TooltipTrigger>
<TooltipContent className="max-w-xs">
<div className="space-y-1 text-sm">
<p>
<strong>rerank_url</strong>: {t('models.rerankUrlTooltip')}
</p>
<p>
<strong>rerank_path</strong>:{' '}
{t('models.rerankPathTooltip')}
</p>
</div>
</TooltipContent>
</Tooltip>
)}
</div>
{!disabled && (
<Button
type="button"
variant="ghost"
size="sm"
className="h-6 text-xs"
onClick={handleAdd}
>
<Plus className="h-3 w-3 mr-1" />
{t('models.addParameter')}
</Button>
)}
</div>
{args.length === 0 ? (
<p className="text-sm text-muted-foreground">{t('common.none')}</p>
) : (
args.map((arg, index) => (
<div key={index} className="flex gap-2 items-center">
<Input
placeholder={t('models.keyName')}
value={arg.key}
className="flex-1"
disabled={disabled}
onChange={(e) => handleUpdate(index, 'key', e.target.value)}
/>
<Select
value={arg.type}
disabled={disabled}
onValueChange={(value) => handleUpdate(index, 'type', value)}
>
<SelectTrigger className="w-24">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="string">{t('models.string')}</SelectItem>
<SelectItem value="number">{t('models.number')}</SelectItem>
<SelectItem value="boolean">{t('models.boolean')}</SelectItem>
</SelectContent>
</Select>
<Input
placeholder={t('models.value')}
value={arg.value}
className="flex-1"
disabled={disabled}
onChange={(e) => handleUpdate(index, 'value', e.target.value)}
/>
{!disabled && (
<Button
type="button"
variant="ghost"
size="icon"
className="h-8 w-8 flex-shrink-0"
onClick={() => handleRemove(index)}
>
<X className="h-4 w-4" />
</Button>
)}
</div>
))
)}
</div>
);
}