All files / src/hooks useModels.js

52.27% Statements 23/44
24% Branches 6/25
30% Functions 6/20
65.71% Lines 23/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79            10x 10x 10x   10x 10x 10x 10x   10x 10x   10x 3x 3x               10x           10x                               10x 6x 6x 6x       10x 3x 3x   3x     10x                            
import { useState, useEffect } from 'react';
import { api } from '../api';
import { DEFAULT_MODEL_ID, DEFAULT_PROVIDER } from '../constants';
import { vscodeNative } from '../vscodeNative';
 
export function useModels({ notify }) {
  const [models, setModels] = useState([]);
  const [modelsLoading, setModelsLoading] = useState(true);
  const [selectedModelId, setSelectedModelId] = useState(DEFAULT_MODEL_ID);
 
  const selectedModelObj = models.find(m => m.id === selectedModelId);
  const selectableModels = models.filter(m => !m.deepResearch);
  const availableProviders = [...new Set(selectableModels.map(m => m.provider))];
  const deepResearchModels = models.filter(m => m.deepResearch);
 
  const getProvider = () => selectedModelObj?.provider || DEFAULT_PROVIDER;
  const getModelId = () => selectedModelId || DEFAULT_MODEL_ID;
 
  const applyModels = (fetched) => {
    setModels(fetched);
    Iif (fetched.length > 0 && !fetched.find(m => m.id === selectedModelId)) {
      const def = fetched.find(m => m.id === DEFAULT_MODEL_ID)
        || fetched.find(m => !m.deepResearch)
        || fetched[0];
      setSelectedModelId(def.id);
    }
  };
 
  const refreshModels = () => {
    api.refreshModels()
      .then(data => applyModels(data.models || []))
      .catch(() => {});
  };
 
  const selectModelViaPicker = async () => {
    if (selectableModels.length === 0) {
      notify('No models available. Configure API keys first.');
      return;
    }
    const items = selectableModels.map(m => ({
      label: m.name || m.id,
      description: m.provider,
      detail: m.id,
    }));
    const picked = await vscodeNative.quickPick(items, { placeHolder: 'Select a model' });
    if (picked) {
      setSelectedModelId(picked.detail);
    }
  };
 
  useEffect(() => {
    Eif (selectedModelId) {
      const model = models.find(m => m.id === selectedModelId);
      vscodeNative.updateStatusBar({ model: model?.name || selectedModelId });
    }
  }, [selectedModelId, models]);
 
  useEffect(() => {
    api.getModels()
      .then(data => applyModels(data.models || []))
      .catch(() => notify('Failed to load models'))
      .finally(() => setModelsLoading(false));
  }, []);
 
  return {
    models, setModels,
    modelsLoading, setModelsLoading,
    selectedModelId, setSelectedModelId,
    selectedModelObj,
    selectableModels,
    availableProviders,
    deepResearchModels,
    getProvider,
    getModelId,
    refreshModels,
    selectModelViaPicker,
  };
}