File size: 2,250 Bytes
9438a57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import { useI18n, type MsgKey } from '../i18n';
import type { Health, ModelOption, ProviderId } from '../types';

export const OPEN_CONNECTIONS = 'testajani:open-connections';
export const openConnections = () => window.dispatchEvent(new Event(OPEN_CONNECTIONS));

export function providerOf(id: string | null | undefined): ProviderId {
  if (id?.startsWith('openai:')) return 'openai';
  if (id?.startsWith('anthropic:')) return 'anthropic';
  return 'ollama';
}

export const PROVIDER_LABEL: Record<ProviderId, string> = { ollama: 'Ollama', openai: 'OpenAI', anthropic: 'Claude' };

/** Tüm sağlayıcıların modelleri (sağlık yanıtı eskiyse yalnızca Ollama). */
export function allModels(health: Health | null): ModelOption[] {
  if (!health) return [];
  return health.models_all || health.ollama.models.map((m) => ({ id: m, provider: 'ollama' as const, name: m }));
}

export function modelName(id: string, health: Health | null): string {
  return allModels(health).find((m) => m.id === id)?.name || id.replace(/^(openai|anthropic):/, '');
}

const ORDER: ProviderId[] = ['ollama', 'openai', 'anthropic'];

export default function ModelSelect({ health, value, onChange, style }: {
  health: Health | null; value: string; onChange: (v: string) => void; style?: React.CSSProperties;
}) {
  const { t } = useI18n();
  const models = allModels(health);
  const known = models.some((m) => m.id === value);
  const groups = ORDER.map((p) => ({ p, items: models.filter((m) => m.provider === p) })).filter((g) => g.items.length);
  if (!models.length) {
    return <input type="text" value={value} onChange={(e) => onChange(e.target.value)} style={{ width: 170, ...style }} />;
  }
  return (
    <select value={value} style={style} onChange={(e) => {
      if (e.target.value === '__add__') { openConnections(); return; }
      onChange(e.target.value);
    }}>
      {!known && value && <option value={value}>{t('ws.notInstalled', { m: value })}</option>}
      {groups.map((g) => (
        <optgroup key={g.p} label={t(`model.group.${g.p}` as MsgKey)}>
          {g.items.map((m) => <option key={m.id} value={m.id}>{m.name}</option>)}
        </optgroup>
      ))}
      <option value="__add__">{t('model.add')}</option>
    </select>
  );
}