index.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
  2. export const getModels = async (token: string = '') => {
  3. let error = null;
  4. const res = await fetch(`${WEBUI_BASE_URL}/api/models`, {
  5. method: 'GET',
  6. headers: {
  7. Accept: 'application/json',
  8. 'Content-Type': 'application/json',
  9. ...(token && { authorization: `Bearer ${token}` })
  10. }
  11. })
  12. .then(async (res) => {
  13. if (!res.ok) throw await res.json();
  14. return res.json();
  15. })
  16. .catch((err) => {
  17. console.log(err);
  18. error = err;
  19. return null;
  20. });
  21. if (error) {
  22. throw error;
  23. }
  24. let models = res?.data ?? [];
  25. models = models
  26. .filter((models) => models)
  27. // Sort the models
  28. .sort((a, b) => {
  29. // Check if models have position property
  30. const aHasPosition = a.info?.meta?.position !== undefined;
  31. const bHasPosition = b.info?.meta?.position !== undefined;
  32. // If both a and b have the position property
  33. if (aHasPosition && bHasPosition) {
  34. return a.info.meta.position - b.info.meta.position;
  35. }
  36. // If only a has the position property, it should come first
  37. if (aHasPosition) return -1;
  38. // If only b has the position property, it should come first
  39. if (bHasPosition) return 1;
  40. // Compare case-insensitively by name for models without position property
  41. const lowerA = a.name.toLowerCase();
  42. const lowerB = b.name.toLowerCase();
  43. if (lowerA < lowerB) return -1;
  44. if (lowerA > lowerB) return 1;
  45. // If same case-insensitively, sort by original strings,
  46. // lowercase will come before uppercase due to ASCII values
  47. if (a.name < b.name) return -1;
  48. if (a.name > b.name) return 1;
  49. return 0; // They are equal
  50. });
  51. console.log(models);
  52. return models;
  53. };
  54. type ChatCompletedForm = {
  55. model: string;
  56. messages: string[];
  57. chat_id: string;
  58. };
  59. export const chatCompleted = async (token: string, body: ChatCompletedForm) => {
  60. let error = null;
  61. const res = await fetch(`${WEBUI_BASE_URL}/api/chat/completed`, {
  62. method: 'POST',
  63. headers: {
  64. Accept: 'application/json',
  65. 'Content-Type': 'application/json',
  66. ...(token && { authorization: `Bearer ${token}` })
  67. },
  68. body: JSON.stringify(body)
  69. })
  70. .then(async (res) => {
  71. if (!res.ok) throw await res.json();
  72. return res.json();
  73. })
  74. .catch((err) => {
  75. console.log(err);
  76. if ('detail' in err) {
  77. error = err.detail;
  78. } else {
  79. error = err;
  80. }
  81. return null;
  82. });
  83. if (error) {
  84. throw error;
  85. }
  86. return res;
  87. };
  88. export const getTaskConfig = async (token: string = '') => {
  89. let error = null;
  90. const res = await fetch(`${WEBUI_BASE_URL}/api/task/config`, {
  91. method: 'GET',
  92. headers: {
  93. Accept: 'application/json',
  94. 'Content-Type': 'application/json',
  95. ...(token && { authorization: `Bearer ${token}` })
  96. }
  97. })
  98. .then(async (res) => {
  99. if (!res.ok) throw await res.json();
  100. return res.json();
  101. })
  102. .catch((err) => {
  103. console.log(err);
  104. error = err;
  105. return null;
  106. });
  107. if (error) {
  108. throw error;
  109. }
  110. return res;
  111. };
  112. export const updateTaskConfig = async (token: string, config: object) => {
  113. let error = null;
  114. const res = await fetch(`${WEBUI_BASE_URL}/api/task/config/update`, {
  115. method: 'POST',
  116. headers: {
  117. Accept: 'application/json',
  118. 'Content-Type': 'application/json',
  119. ...(token && { authorization: `Bearer ${token}` })
  120. },
  121. body: JSON.stringify(config)
  122. })
  123. .then(async (res) => {
  124. if (!res.ok) throw await res.json();
  125. return res.json();
  126. })
  127. .catch((err) => {
  128. console.log(err);
  129. if ('detail' in err) {
  130. error = err.detail;
  131. } else {
  132. error = err;
  133. }
  134. return null;
  135. });
  136. if (error) {
  137. throw error;
  138. }
  139. return res;
  140. };
  141. export const generateTitle = async (
  142. token: string = '',
  143. model: string,
  144. prompt: string,
  145. chat_id?: string
  146. ) => {
  147. let error = null;
  148. const res = await fetch(`${WEBUI_BASE_URL}/api/task/title/completions`, {
  149. method: 'POST',
  150. headers: {
  151. Accept: 'application/json',
  152. 'Content-Type': 'application/json',
  153. Authorization: `Bearer ${token}`
  154. },
  155. body: JSON.stringify({
  156. model: model,
  157. prompt: prompt,
  158. ...(chat_id && { chat_id: chat_id })
  159. })
  160. })
  161. .then(async (res) => {
  162. if (!res.ok) throw await res.json();
  163. return res.json();
  164. })
  165. .catch((err) => {
  166. console.log(err);
  167. if ('detail' in err) {
  168. error = err.detail;
  169. }
  170. return null;
  171. });
  172. if (error) {
  173. throw error;
  174. }
  175. return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? 'New Chat';
  176. };
  177. export const generateEmoji = async (
  178. token: string = '',
  179. model: string,
  180. prompt: string,
  181. chat_id?: string
  182. ) => {
  183. let error = null;
  184. const res = await fetch(`${WEBUI_BASE_URL}/api/task/emoji/completions`, {
  185. method: 'POST',
  186. headers: {
  187. Accept: 'application/json',
  188. 'Content-Type': 'application/json',
  189. Authorization: `Bearer ${token}`
  190. },
  191. body: JSON.stringify({
  192. model: model,
  193. prompt: prompt,
  194. ...(chat_id && { chat_id: chat_id })
  195. })
  196. })
  197. .then(async (res) => {
  198. if (!res.ok) throw await res.json();
  199. return res.json();
  200. })
  201. .catch((err) => {
  202. console.log(err);
  203. if ('detail' in err) {
  204. error = err.detail;
  205. }
  206. return null;
  207. });
  208. if (error) {
  209. throw error;
  210. }
  211. return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? null;
  212. };
  213. export const generateSearchQuery = async (
  214. token: string = '',
  215. model: string,
  216. messages: object[],
  217. prompt: string
  218. ) => {
  219. let error = null;
  220. const res = await fetch(`${WEBUI_BASE_URL}/api/task/query/completions`, {
  221. method: 'POST',
  222. headers: {
  223. Accept: 'application/json',
  224. 'Content-Type': 'application/json',
  225. Authorization: `Bearer ${token}`
  226. },
  227. body: JSON.stringify({
  228. model: model,
  229. messages: messages,
  230. prompt: prompt
  231. })
  232. })
  233. .then(async (res) => {
  234. if (!res.ok) throw await res.json();
  235. return res.json();
  236. })
  237. .catch((err) => {
  238. console.log(err);
  239. if ('detail' in err) {
  240. error = err.detail;
  241. }
  242. return null;
  243. });
  244. if (error) {
  245. throw error;
  246. }
  247. return res?.choices[0]?.message?.content.replace(/["']/g, '') ?? prompt;
  248. };
  249. export const getPipelinesList = async (token: string = '') => {
  250. let error = null;
  251. const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/list`, {
  252. method: 'GET',
  253. headers: {
  254. Accept: 'application/json',
  255. 'Content-Type': 'application/json',
  256. ...(token && { authorization: `Bearer ${token}` })
  257. }
  258. })
  259. .then(async (res) => {
  260. if (!res.ok) throw await res.json();
  261. return res.json();
  262. })
  263. .catch((err) => {
  264. console.log(err);
  265. error = err;
  266. return null;
  267. });
  268. if (error) {
  269. throw error;
  270. }
  271. let pipelines = res?.data ?? [];
  272. return pipelines;
  273. };
  274. export const uploadPipeline = async (token: string, file: File, urlIdx: string) => {
  275. let error = null;
  276. // Create a new FormData object to handle the file upload
  277. const formData = new FormData();
  278. formData.append('file', file);
  279. formData.append('urlIdx', urlIdx);
  280. const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/upload`, {
  281. method: 'POST',
  282. headers: {
  283. ...(token && { authorization: `Bearer ${token}` })
  284. // 'Content-Type': 'multipart/form-data' is not needed as Fetch API will set it automatically
  285. },
  286. body: formData
  287. })
  288. .then(async (res) => {
  289. if (!res.ok) throw await res.json();
  290. return res.json();
  291. })
  292. .catch((err) => {
  293. console.log(err);
  294. if ('detail' in err) {
  295. error = err.detail;
  296. } else {
  297. error = err;
  298. }
  299. return null;
  300. });
  301. if (error) {
  302. throw error;
  303. }
  304. return res;
  305. };
  306. export const downloadPipeline = async (token: string, url: string, urlIdx: string) => {
  307. let error = null;
  308. const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/add`, {
  309. method: 'POST',
  310. headers: {
  311. Accept: 'application/json',
  312. 'Content-Type': 'application/json',
  313. ...(token && { authorization: `Bearer ${token}` })
  314. },
  315. body: JSON.stringify({
  316. url: url,
  317. urlIdx: urlIdx
  318. })
  319. })
  320. .then(async (res) => {
  321. if (!res.ok) throw await res.json();
  322. return res.json();
  323. })
  324. .catch((err) => {
  325. console.log(err);
  326. if ('detail' in err) {
  327. error = err.detail;
  328. } else {
  329. error = err;
  330. }
  331. return null;
  332. });
  333. if (error) {
  334. throw error;
  335. }
  336. return res;
  337. };
  338. export const deletePipeline = async (token: string, id: string, urlIdx: string) => {
  339. let error = null;
  340. const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines/delete`, {
  341. method: 'DELETE',
  342. headers: {
  343. Accept: 'application/json',
  344. 'Content-Type': 'application/json',
  345. ...(token && { authorization: `Bearer ${token}` })
  346. },
  347. body: JSON.stringify({
  348. id: id,
  349. urlIdx: urlIdx
  350. })
  351. })
  352. .then(async (res) => {
  353. if (!res.ok) throw await res.json();
  354. return res.json();
  355. })
  356. .catch((err) => {
  357. console.log(err);
  358. if ('detail' in err) {
  359. error = err.detail;
  360. } else {
  361. error = err;
  362. }
  363. return null;
  364. });
  365. if (error) {
  366. throw error;
  367. }
  368. return res;
  369. };
  370. export const getPipelines = async (token: string, urlIdx?: string) => {
  371. let error = null;
  372. const searchParams = new URLSearchParams();
  373. if (urlIdx !== undefined) {
  374. searchParams.append('urlIdx', urlIdx);
  375. }
  376. const res = await fetch(`${WEBUI_BASE_URL}/api/pipelines?${searchParams.toString()}`, {
  377. method: 'GET',
  378. headers: {
  379. Accept: 'application/json',
  380. 'Content-Type': 'application/json',
  381. ...(token && { authorization: `Bearer ${token}` })
  382. }
  383. })
  384. .then(async (res) => {
  385. if (!res.ok) throw await res.json();
  386. return res.json();
  387. })
  388. .catch((err) => {
  389. console.log(err);
  390. error = err;
  391. return null;
  392. });
  393. if (error) {
  394. throw error;
  395. }
  396. let pipelines = res?.data ?? [];
  397. return pipelines;
  398. };
  399. export const getPipelineValves = async (token: string, pipeline_id: string, urlIdx: string) => {
  400. let error = null;
  401. const searchParams = new URLSearchParams();
  402. if (urlIdx !== undefined) {
  403. searchParams.append('urlIdx', urlIdx);
  404. }
  405. const res = await fetch(
  406. `${WEBUI_BASE_URL}/api/pipelines/${pipeline_id}/valves?${searchParams.toString()}`,
  407. {
  408. method: 'GET',
  409. headers: {
  410. Accept: 'application/json',
  411. 'Content-Type': 'application/json',
  412. ...(token && { authorization: `Bearer ${token}` })
  413. }
  414. }
  415. )
  416. .then(async (res) => {
  417. if (!res.ok) throw await res.json();
  418. return res.json();
  419. })
  420. .catch((err) => {
  421. console.log(err);
  422. error = err;
  423. return null;
  424. });
  425. if (error) {
  426. throw error;
  427. }
  428. return res;
  429. };
  430. export const getPipelineValvesSpec = async (token: string, pipeline_id: string, urlIdx: string) => {
  431. let error = null;
  432. const searchParams = new URLSearchParams();
  433. if (urlIdx !== undefined) {
  434. searchParams.append('urlIdx', urlIdx);
  435. }
  436. const res = await fetch(
  437. `${WEBUI_BASE_URL}/api/pipelines/${pipeline_id}/valves/spec?${searchParams.toString()}`,
  438. {
  439. method: 'GET',
  440. headers: {
  441. Accept: 'application/json',
  442. 'Content-Type': 'application/json',
  443. ...(token && { authorization: `Bearer ${token}` })
  444. }
  445. }
  446. )
  447. .then(async (res) => {
  448. if (!res.ok) throw await res.json();
  449. return res.json();
  450. })
  451. .catch((err) => {
  452. console.log(err);
  453. error = err;
  454. return null;
  455. });
  456. if (error) {
  457. throw error;
  458. }
  459. return res;
  460. };
  461. export const updatePipelineValves = async (
  462. token: string = '',
  463. pipeline_id: string,
  464. valves: object,
  465. urlIdx: string
  466. ) => {
  467. let error = null;
  468. const searchParams = new URLSearchParams();
  469. if (urlIdx !== undefined) {
  470. searchParams.append('urlIdx', urlIdx);
  471. }
  472. const res = await fetch(
  473. `${WEBUI_BASE_URL}/api/pipelines/${pipeline_id}/valves/update?${searchParams.toString()}`,
  474. {
  475. method: 'POST',
  476. headers: {
  477. Accept: 'application/json',
  478. 'Content-Type': 'application/json',
  479. ...(token && { authorization: `Bearer ${token}` })
  480. },
  481. body: JSON.stringify(valves)
  482. }
  483. )
  484. .then(async (res) => {
  485. if (!res.ok) throw await res.json();
  486. return res.json();
  487. })
  488. .catch((err) => {
  489. console.log(err);
  490. if ('detail' in err) {
  491. error = err.detail;
  492. } else {
  493. error = err;
  494. }
  495. return null;
  496. });
  497. if (error) {
  498. throw error;
  499. }
  500. return res;
  501. };
  502. export const getBackendConfig = async () => {
  503. let error = null;
  504. const res = await fetch(`${WEBUI_BASE_URL}/api/config`, {
  505. method: 'GET',
  506. headers: {
  507. 'Content-Type': 'application/json'
  508. }
  509. })
  510. .then(async (res) => {
  511. if (!res.ok) throw await res.json();
  512. return res.json();
  513. })
  514. .catch((err) => {
  515. console.log(err);
  516. error = err;
  517. return null;
  518. });
  519. if (error) {
  520. throw error;
  521. }
  522. return res;
  523. };
  524. export const getChangelog = async () => {
  525. let error = null;
  526. const res = await fetch(`${WEBUI_BASE_URL}/api/changelog`, {
  527. method: 'GET',
  528. headers: {
  529. 'Content-Type': 'application/json'
  530. }
  531. })
  532. .then(async (res) => {
  533. if (!res.ok) throw await res.json();
  534. return res.json();
  535. })
  536. .catch((err) => {
  537. console.log(err);
  538. error = err;
  539. return null;
  540. });
  541. if (error) {
  542. throw error;
  543. }
  544. return res;
  545. };
  546. export const getVersionUpdates = async () => {
  547. let error = null;
  548. const res = await fetch(`${WEBUI_BASE_URL}/api/version/updates`, {
  549. method: 'GET',
  550. headers: {
  551. 'Content-Type': 'application/json'
  552. }
  553. })
  554. .then(async (res) => {
  555. if (!res.ok) throw await res.json();
  556. return res.json();
  557. })
  558. .catch((err) => {
  559. console.log(err);
  560. error = err;
  561. return null;
  562. });
  563. if (error) {
  564. throw error;
  565. }
  566. return res;
  567. };
  568. export const getModelFilterConfig = async (token: string) => {
  569. let error = null;
  570. const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, {
  571. method: 'GET',
  572. headers: {
  573. 'Content-Type': 'application/json',
  574. Authorization: `Bearer ${token}`
  575. }
  576. })
  577. .then(async (res) => {
  578. if (!res.ok) throw await res.json();
  579. return res.json();
  580. })
  581. .catch((err) => {
  582. console.log(err);
  583. error = err;
  584. return null;
  585. });
  586. if (error) {
  587. throw error;
  588. }
  589. return res;
  590. };
  591. export const updateModelFilterConfig = async (
  592. token: string,
  593. enabled: boolean,
  594. models: string[]
  595. ) => {
  596. let error = null;
  597. const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, {
  598. method: 'POST',
  599. headers: {
  600. 'Content-Type': 'application/json',
  601. Authorization: `Bearer ${token}`
  602. },
  603. body: JSON.stringify({
  604. enabled: enabled,
  605. models: models
  606. })
  607. })
  608. .then(async (res) => {
  609. if (!res.ok) throw await res.json();
  610. return res.json();
  611. })
  612. .catch((err) => {
  613. console.log(err);
  614. error = err;
  615. return null;
  616. });
  617. if (error) {
  618. throw error;
  619. }
  620. return res;
  621. };
  622. export const getWebhookUrl = async (token: string) => {
  623. let error = null;
  624. const res = await fetch(`${WEBUI_BASE_URL}/api/webhook`, {
  625. method: 'GET',
  626. headers: {
  627. 'Content-Type': 'application/json',
  628. Authorization: `Bearer ${token}`
  629. }
  630. })
  631. .then(async (res) => {
  632. if (!res.ok) throw await res.json();
  633. return res.json();
  634. })
  635. .catch((err) => {
  636. console.log(err);
  637. error = err;
  638. return null;
  639. });
  640. if (error) {
  641. throw error;
  642. }
  643. return res.url;
  644. };
  645. export const updateWebhookUrl = async (token: string, url: string) => {
  646. let error = null;
  647. const res = await fetch(`${WEBUI_BASE_URL}/api/webhook`, {
  648. method: 'POST',
  649. headers: {
  650. 'Content-Type': 'application/json',
  651. Authorization: `Bearer ${token}`
  652. },
  653. body: JSON.stringify({
  654. url: url
  655. })
  656. })
  657. .then(async (res) => {
  658. if (!res.ok) throw await res.json();
  659. return res.json();
  660. })
  661. .catch((err) => {
  662. console.log(err);
  663. error = err;
  664. return null;
  665. });
  666. if (error) {
  667. throw error;
  668. }
  669. return res.url;
  670. };
  671. export const getCommunitySharingEnabledStatus = async (token: string) => {
  672. let error = null;
  673. const res = await fetch(`${WEBUI_BASE_URL}/api/community_sharing`, {
  674. method: 'GET',
  675. headers: {
  676. 'Content-Type': 'application/json',
  677. Authorization: `Bearer ${token}`
  678. }
  679. })
  680. .then(async (res) => {
  681. if (!res.ok) throw await res.json();
  682. return res.json();
  683. })
  684. .catch((err) => {
  685. console.log(err);
  686. error = err;
  687. return null;
  688. });
  689. if (error) {
  690. throw error;
  691. }
  692. return res;
  693. };
  694. export const toggleCommunitySharingEnabledStatus = async (token: string) => {
  695. let error = null;
  696. const res = await fetch(`${WEBUI_BASE_URL}/api/community_sharing/toggle`, {
  697. method: 'GET',
  698. headers: {
  699. 'Content-Type': 'application/json',
  700. Authorization: `Bearer ${token}`
  701. }
  702. })
  703. .then(async (res) => {
  704. if (!res.ok) throw await res.json();
  705. return res.json();
  706. })
  707. .catch((err) => {
  708. console.log(err);
  709. error = err.detail;
  710. return null;
  711. });
  712. if (error) {
  713. throw error;
  714. }
  715. return res;
  716. };
  717. export const getModelConfig = async (token: string): Promise<GlobalModelConfig> => {
  718. let error = null;
  719. const res = await fetch(`${WEBUI_BASE_URL}/api/config/models`, {
  720. method: 'GET',
  721. headers: {
  722. 'Content-Type': 'application/json',
  723. Authorization: `Bearer ${token}`
  724. }
  725. })
  726. .then(async (res) => {
  727. if (!res.ok) throw await res.json();
  728. return res.json();
  729. })
  730. .catch((err) => {
  731. console.log(err);
  732. error = err;
  733. return null;
  734. });
  735. if (error) {
  736. throw error;
  737. }
  738. return res.models;
  739. };
  740. export interface ModelConfig {
  741. id: string;
  742. name: string;
  743. meta: ModelMeta;
  744. base_model_id?: string;
  745. params: ModelParams;
  746. }
  747. export interface ModelMeta {
  748. description?: string;
  749. capabilities?: object;
  750. }
  751. export interface ModelParams {}
  752. export type GlobalModelConfig = ModelConfig[];
  753. export const updateModelConfig = async (token: string, config: GlobalModelConfig) => {
  754. let error = null;
  755. const res = await fetch(`${WEBUI_BASE_URL}/api/config/models`, {
  756. method: 'POST',
  757. headers: {
  758. 'Content-Type': 'application/json',
  759. Authorization: `Bearer ${token}`
  760. },
  761. body: JSON.stringify({
  762. models: config
  763. })
  764. })
  765. .then(async (res) => {
  766. if (!res.ok) throw await res.json();
  767. return res.json();
  768. })
  769. .catch((err) => {
  770. console.log(err);
  771. error = err;
  772. return null;
  773. });
  774. if (error) {
  775. throw error;
  776. }
  777. return res;
  778. };