CodeExecution.svelte 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <script lang="ts">
  2. import { toast } from 'svelte-sonner';
  3. import { onMount, getContext } from 'svelte';
  4. import { getCodeExecutionConfig, setCodeExecutionConfig } from '$lib/apis/configs';
  5. import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
  6. import Tooltip from '$lib/components/common/Tooltip.svelte';
  7. import Textarea from '$lib/components/common/Textarea.svelte';
  8. import Switch from '$lib/components/common/Switch.svelte';
  9. const i18n = getContext('i18n');
  10. export let saveHandler: Function;
  11. let config = null;
  12. let engines = ['pyodide', 'jupyter'];
  13. const submitHandler = async () => {
  14. const res = await setCodeExecutionConfig(localStorage.token, config);
  15. };
  16. onMount(async () => {
  17. const res = await getCodeExecutionConfig(localStorage.token);
  18. if (res) {
  19. config = res;
  20. }
  21. });
  22. </script>
  23. <form
  24. class="flex flex-col h-full justify-between space-y-3 text-sm"
  25. on:submit|preventDefault={async () => {
  26. await submitHandler();
  27. saveHandler();
  28. }}
  29. >
  30. <div class=" space-y-3 overflow-y-scroll scrollbar-hidden h-full">
  31. {#if config}
  32. <div>
  33. <div class="mb-3.5">
  34. <div class=" mb-2.5 text-base font-medium">{$i18n.t('General')}</div>
  35. <hr class=" border-gray-100 dark:border-gray-850 my-2" />
  36. <div class=" py-0.5 flex w-full justify-between">
  37. <div class=" self-center text-xs font-medium">{$i18n.t('Code Execution Engine')}</div>
  38. <div class="flex items-center relative">
  39. <select
  40. class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
  41. bind:value={config.CODE_EXECUTION_ENGINE}
  42. placeholder={$i18n.t('Select a engine')}
  43. required
  44. >
  45. <option disabled selected value="">{$i18n.t('Select a engine')}</option>
  46. {#each engines as engine}
  47. <option value={engine}>{engine}</option>
  48. {/each}
  49. </select>
  50. </div>
  51. </div>
  52. {#if config.CODE_EXECUTION_ENGINE === 'jupyter'}
  53. <div class="mt-1 flex flex-col gap-1.5 mb-1 w-full">
  54. <div class="text-xs font-medium">
  55. {$i18n.t('Jupyter URL')}
  56. </div>
  57. <div class="flex w-full">
  58. <div class="flex-1">
  59. <input
  60. class="w-full text-sm py-0.5 placeholder:text-gray-300 dark:placeholder:text-gray-700 bg-transparent outline-hidden"
  61. type="text"
  62. placeholder={$i18n.t('Enter Jupyter URL')}
  63. bind:value={config.CODE_EXECUTION_JUPYTER_URL}
  64. autocomplete="off"
  65. />
  66. </div>
  67. </div>
  68. </div>
  69. <div class="mt-1 flex gap-2 mb-1 w-full items-center justify-between">
  70. <div class="text-xs font-medium">
  71. {$i18n.t('Jupyter Auth')}
  72. </div>
  73. <div>
  74. <select
  75. class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-left"
  76. bind:value={config.CODE_EXECUTION_JUPYTER_AUTH}
  77. placeholder={$i18n.t('Select an auth method')}
  78. >
  79. <option selected value="">{$i18n.t('None')}</option>
  80. <option value="token">{$i18n.t('Token')}</option>
  81. <option value="password">{$i18n.t('Password')}</option>
  82. </select>
  83. </div>
  84. </div>
  85. {#if config.CODE_EXECUTION_JUPYTER_AUTH}
  86. <div class="flex w-full gap-2">
  87. <div class="flex-1">
  88. {#if config.CODE_EXECUTION_JUPYTER_AUTH === 'password'}
  89. <SensitiveInput
  90. type="text"
  91. placeholder={$i18n.t('Enter Jupyter Password')}
  92. bind:value={config.CODE_EXECUTION_JUPYTER_AUTH_PASSWORD}
  93. autocomplete="off"
  94. />
  95. {:else}
  96. <SensitiveInput
  97. type="text"
  98. placeholder={$i18n.t('Enter Jupyter Token')}
  99. bind:value={config.CODE_EXECUTION_JUPYTER_AUTH_TOKEN}
  100. autocomplete="off"
  101. />
  102. {/if}
  103. </div>
  104. </div>
  105. {/if}
  106. {/if}
  107. </div>
  108. <div class="mb-3.5">
  109. <div class=" mb-2.5 text-base font-medium">{$i18n.t('Code Interpreter')}</div>
  110. <hr class=" border-gray-100 dark:border-gray-850 my-2" />
  111. <div>
  112. <div class=" py-0.5 flex w-full justify-between">
  113. <div class=" self-center text-xs font-medium">
  114. {$i18n.t('Enable Code Interpreter')}
  115. </div>
  116. <Switch bind:state={config.ENABLE_CODE_INTERPRETER} />
  117. </div>
  118. </div>
  119. {#if config.ENABLE_CODE_INTERPRETER}
  120. <div class=" py-0.5 flex w-full justify-between">
  121. <div class=" self-center text-xs font-medium">
  122. {$i18n.t('Code Interpreter Engine')}
  123. </div>
  124. <div class="flex items-center relative">
  125. <select
  126. class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
  127. bind:value={config.CODE_INTERPRETER_ENGINE}
  128. placeholder={$i18n.t('Select a engine')}
  129. required
  130. >
  131. <option disabled selected value="">{$i18n.t('Select a engine')}</option>
  132. {#each engines as engine}
  133. <option value={engine}>{engine}</option>
  134. {/each}
  135. </select>
  136. </div>
  137. </div>
  138. {#if config.CODE_INTERPRETER_ENGINE === 'jupyter'}
  139. <div class="mt-1 flex flex-col gap-1.5 mb-1 w-full">
  140. <div class="text-xs font-medium">
  141. {$i18n.t('Jupyter URL')}
  142. </div>
  143. <div class="flex w-full">
  144. <div class="flex-1">
  145. <input
  146. class="w-full text-sm py-0.5 placeholder:text-gray-300 dark:placeholder:text-gray-700 bg-transparent outline-hidden"
  147. type="text"
  148. placeholder={$i18n.t('Enter Jupyter URL')}
  149. bind:value={config.CODE_INTERPRETER_JUPYTER_URL}
  150. autocomplete="off"
  151. />
  152. </div>
  153. </div>
  154. </div>
  155. <div class="mt-1 flex gap-2 mb-1 w-full items-center justify-between">
  156. <div class="text-xs font-medium">
  157. {$i18n.t('Jupyter Auth')}
  158. </div>
  159. <div>
  160. <select
  161. class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-left"
  162. bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH}
  163. placeholder={$i18n.t('Select an auth method')}
  164. >
  165. <option selected value="">{$i18n.t('None')}</option>
  166. <option value="token">{$i18n.t('Token')}</option>
  167. <option value="password">{$i18n.t('Password')}</option>
  168. </select>
  169. </div>
  170. </div>
  171. {#if config.CODE_INTERPRETER_JUPYTER_AUTH}
  172. <div class="flex w-full gap-2">
  173. <div class="flex-1">
  174. {#if config.CODE_INTERPRETER_JUPYTER_AUTH === 'password'}
  175. <SensitiveInput
  176. type="text"
  177. placeholder={$i18n.t('Enter Jupyter Password')}
  178. bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD}
  179. autocomplete="off"
  180. />
  181. {:else}
  182. <SensitiveInput
  183. type="text"
  184. placeholder={$i18n.t('Enter Jupyter Token')}
  185. bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN}
  186. autocomplete="off"
  187. />
  188. {/if}
  189. </div>
  190. </div>
  191. {/if}
  192. {/if}
  193. <hr class="border-gray-100 dark:border-gray-850 my-2" />
  194. <div>
  195. <div class="py-0.5 w-full">
  196. <div class=" mb-2.5 text-xs font-medium">
  197. {$i18n.t('Code Interpreter Prompt Template')}
  198. </div>
  199. <Tooltip
  200. content={$i18n.t(
  201. 'Leave empty to use the default prompt, or enter a custom prompt'
  202. )}
  203. placement="top-start"
  204. >
  205. <Textarea
  206. bind:value={config.CODE_INTERPRETER_PROMPT_TEMPLATE}
  207. placeholder={$i18n.t(
  208. 'Leave empty to use the default prompt, or enter a custom prompt'
  209. )}
  210. />
  211. </Tooltip>
  212. </div>
  213. </div>
  214. {/if}
  215. </div>
  216. </div>
  217. {/if}
  218. </div>
  219. <div class="flex justify-end pt-3 text-sm font-medium">
  220. <button
  221. 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"
  222. type="submit"
  223. >
  224. {$i18n.t('Save')}
  225. </button>
  226. </div>
  227. </form>