Evaluations.svelte 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <script lang="ts">
  2. import { toast } from 'svelte-sonner';
  3. import { models, settings, user } from '$lib/stores';
  4. import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
  5. const dispatch = createEventDispatcher();
  6. import { getModels } from '$lib/apis';
  7. import { getConfig, updateConfig } from '$lib/apis/evaluations';
  8. import Switch from '$lib/components/common/Switch.svelte';
  9. import Spinner from '$lib/components/common/Spinner.svelte';
  10. import Tooltip from '$lib/components/common/Tooltip.svelte';
  11. import Plus from '$lib/components/icons/Plus.svelte';
  12. import Model from './Evaluations/Model.svelte';
  13. import ArenaModelModal from './Evaluations/ArenaModelModal.svelte';
  14. const i18n = getContext('i18n');
  15. let config = null;
  16. let showAddModel = false;
  17. const submitHandler = async () => {
  18. config = await updateConfig(localStorage.token, config).catch((err) => {
  19. toast.error(err);
  20. return null;
  21. });
  22. if (config) {
  23. toast.success('Settings saved successfully');
  24. models.set(
  25. await getModels(
  26. localStorage.token,
  27. $config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
  28. )
  29. );
  30. }
  31. };
  32. const addModelHandler = async (model) => {
  33. config.EVALUATION_ARENA_MODELS.push(model);
  34. config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS];
  35. await submitHandler();
  36. models.set(
  37. await getModels(
  38. localStorage.token,
  39. $config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
  40. )
  41. );
  42. };
  43. const editModelHandler = async (model, modelIdx) => {
  44. config.EVALUATION_ARENA_MODELS[modelIdx] = model;
  45. config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS];
  46. await submitHandler();
  47. models.set(
  48. await getModels(
  49. localStorage.token,
  50. $config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
  51. )
  52. );
  53. };
  54. const deleteModelHandler = async (modelIdx) => {
  55. config.EVALUATION_ARENA_MODELS = config.EVALUATION_ARENA_MODELS.filter(
  56. (m, mIdx) => mIdx !== modelIdx
  57. );
  58. await submitHandler();
  59. models.set(
  60. await getModels(
  61. localStorage.token,
  62. $config?.features?.enable_direct_connections && ($settings?.directConnections ?? null)
  63. )
  64. );
  65. };
  66. onMount(async () => {
  67. if ($user.role === 'admin') {
  68. config = await getConfig(localStorage.token).catch((err) => {
  69. toast.error(err);
  70. return null;
  71. });
  72. }
  73. });
  74. </script>
  75. <ArenaModelModal
  76. bind:show={showAddModel}
  77. on:submit={async (e) => {
  78. addModelHandler(e.detail);
  79. }}
  80. />
  81. <form
  82. class="flex flex-col h-full justify-between text-sm"
  83. on:submit|preventDefault={() => {
  84. submitHandler();
  85. dispatch('save');
  86. }}
  87. >
  88. <div class="overflow-y-scroll scrollbar-hidden h-full">
  89. {#if config !== null}
  90. <div class="">
  91. <div class="text-sm font-medium mb-2">{$i18n.t('General Settings')}</div>
  92. <div class=" mb-2">
  93. <div class="flex justify-between items-center text-xs">
  94. <div class=" text-xs font-medium">{$i18n.t('Arena Models')}</div>
  95. <Tooltip content={$i18n.t(`Message rating should be enabled to use this feature`)}>
  96. <Switch bind:state={config.ENABLE_EVALUATION_ARENA_MODELS} />
  97. </Tooltip>
  98. </div>
  99. </div>
  100. {#if config.ENABLE_EVALUATION_ARENA_MODELS}
  101. <hr class=" border-gray-50 dark:border-gray-700/10 my-2" />
  102. <div class="flex justify-between items-center mb-2">
  103. <div class="text-sm font-medium">{$i18n.t('Manage Arena Models')}</div>
  104. <div>
  105. <Tooltip content={$i18n.t('Add Arena Model')}>
  106. <button
  107. class="p-1"
  108. type="button"
  109. on:click={() => {
  110. showAddModel = true;
  111. }}
  112. >
  113. <Plus />
  114. </button>
  115. </Tooltip>
  116. </div>
  117. </div>
  118. <div class="flex flex-col gap-2">
  119. {#if (config?.EVALUATION_ARENA_MODELS ?? []).length > 0}
  120. {#each config.EVALUATION_ARENA_MODELS as model, index}
  121. <Model
  122. {model}
  123. on:edit={(e) => {
  124. editModelHandler(e.detail, index);
  125. }}
  126. on:delete={(e) => {
  127. deleteModelHandler(index);
  128. }}
  129. />
  130. {/each}
  131. {:else}
  132. <div class=" text-center text-xs text-gray-500">
  133. {$i18n.t(
  134. `Using the default arena model with all models. Click the plus button to add custom models.`
  135. )}
  136. </div>
  137. {/if}
  138. </div>
  139. {/if}
  140. </div>
  141. {:else}
  142. <div class="flex h-full justify-center">
  143. <div class="my-auto">
  144. <Spinner className="size-6" />
  145. </div>
  146. </div>
  147. {/if}
  148. </div>
  149. <div class="flex justify-end pt-3 text-sm font-medium">
  150. <button
  151. class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
  152. type="submit"
  153. >
  154. {$i18n.t('Save')}
  155. </button>
  156. </div>
  157. </form>