Tools.svelte 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <script lang="ts">
  2. import { toast } from 'svelte-sonner';
  3. import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
  4. import { getModels as _getModels, getToolServersData } from '$lib/apis';
  5. const dispatch = createEventDispatcher();
  6. const i18n = getContext('i18n');
  7. import { models, settings, toolServers, user } from '$lib/stores';
  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 Connection from './Tools/Connection.svelte';
  13. import AddServerModal from '$lib/components/AddServerModal.svelte';
  14. export let saveSettings: Function;
  15. let servers = null;
  16. let showConnectionModal = false;
  17. const addConnectionHandler = async (server) => {
  18. servers = [...servers, server];
  19. await updateHandler();
  20. };
  21. const updateHandler = async () => {
  22. await saveSettings({
  23. toolServers: servers
  24. });
  25. toolServers.set(await getToolServersData($i18n, $settings?.toolServers ?? []));
  26. };
  27. onMount(async () => {
  28. servers = $settings?.toolServers ?? [];
  29. });
  30. </script>
  31. <AddServerModal bind:show={showConnectionModal} onSubmit={addConnectionHandler} direct />
  32. <form
  33. id="tab-tools"
  34. class="flex flex-col h-full justify-between text-sm"
  35. on:submit|preventDefault={() => {
  36. updateHandler();
  37. }}
  38. >
  39. <div class=" overflow-y-scroll scrollbar-hidden h-full">
  40. {#if servers !== null}
  41. <div class="">
  42. <div class="pr-1.5">
  43. <!-- {$i18n.t(`Failed to connect to {{URL}} OpenAPI tool server`, {
  44. URL: 'server?.url'
  45. })} -->
  46. <div class="">
  47. <div class="flex justify-between items-center mb-0.5">
  48. <div class="font-medium">{$i18n.t('Manage Tool Servers')}</div>
  49. <Tooltip content={$i18n.t(`Add Connection`)}>
  50. <button
  51. aria-label={$i18n.t(`Add Connection`)}
  52. class="px-1"
  53. on:click={() => {
  54. showConnectionModal = true;
  55. }}
  56. type="button"
  57. >
  58. <Plus />
  59. </button>
  60. </Tooltip>
  61. </div>
  62. <div class="flex flex-col gap-1.5">
  63. {#each servers as server, idx}
  64. <Connection
  65. bind:connection={server}
  66. direct
  67. onSubmit={() => {
  68. updateHandler();
  69. }}
  70. onDelete={() => {
  71. servers = servers.filter((_, i) => i !== idx);
  72. updateHandler();
  73. }}
  74. />
  75. {/each}
  76. </div>
  77. </div>
  78. <div class="my-1.5">
  79. <div
  80. class={`text-xs
  81. ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : 'text-gray-500'}`}
  82. >
  83. {$i18n.t('Connect to your own OpenAPI compatible external tool servers.')}
  84. <br />
  85. {$i18n.t(
  86. 'CORS must be properly configured by the provider to allow requests from Open WebUI.'
  87. )}
  88. </div>
  89. </div>
  90. <div class=" text-xs text-gray-600 dark:text-gray-300 mb-2">
  91. <a
  92. class="underline"
  93. href="https://github.com/open-webui/openapi-servers"
  94. target="_blank">{$i18n.t('Learn more about OpenAPI tool servers.')}</a
  95. >
  96. </div>
  97. </div>
  98. </div>
  99. {:else}
  100. <div class="flex h-full justify-center">
  101. <div class="my-auto">
  102. <Spinner className="size-6" />
  103. </div>
  104. </div>
  105. {/if}
  106. </div>
  107. <div class="flex justify-end pt-3 text-sm font-medium">
  108. <button
  109. 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"
  110. type="submit"
  111. >
  112. {$i18n.t('Save')}
  113. </button>
  114. </div>
  115. </form>