diff --git a/app/components/plugin.tsx b/app/components/plugin.tsx index 5aad2c70a..b847ad78e 100644 --- a/app/components/plugin.tsx +++ b/app/components/plugin.tsx @@ -27,6 +27,7 @@ import { import Locale from "../locales"; import { useNavigate } from "react-router-dom"; import { useEffect, useState } from "react"; +import { getClientConfig } from "../config/client"; export function PluginPage() { const navigate = useNavigate(); @@ -293,21 +294,23 @@ export function PluginPage() { > )} - - { - pluginStore.updatePlugin(editingPlugin.id, (plugin) => { - plugin.usingProxy = e.currentTarget.checked; - }); - }} - > - + {!getClientConfig()?.isApp && ( + + { + pluginStore.updatePlugin(editingPlugin.id, (plugin) => { + plugin.usingProxy = e.currentTarget.checked; + }); + }} + > + + )} diff --git a/app/global.d.ts b/app/global.d.ts index 31e2b6e8a..8ee636bcd 100644 --- a/app/global.d.ts +++ b/app/global.d.ts @@ -21,10 +21,16 @@ declare interface Window { writeBinaryFile(path: string, data: Uint8Array): Promise; writeTextFile(path: string, data: string): Promise; }; - notification:{ + notification: { requestPermission(): Promise; isPermissionGranted(): Promise; sendNotification(options: string | Options): void; }; + http: { + fetch( + url: string, + options?: Record, + ): Promise>; + }; }; } diff --git a/app/store/chat.ts b/app/store/chat.ts index db7fe35f0..8b0cc39eb 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -420,7 +420,7 @@ export const useChatStore = createPersistStore( }); }, onError(error) { - const isAborted = error.message.includes("aborted"); + const isAborted = error.message?.includes?.("aborted"); botMessage.content += "\n\n" + prettyObject({ diff --git a/app/store/plugin.ts b/app/store/plugin.ts index 934a989dc..74f0fbe17 100644 --- a/app/store/plugin.ts +++ b/app/store/plugin.ts @@ -4,6 +4,7 @@ import { StoreKey } from "../constant"; import { nanoid } from "nanoid"; import { createPersistStore } from "../utils/store"; import yaml from "js-yaml"; +import { adapter } from "../utils"; export type Plugin = { id: string; @@ -61,6 +62,7 @@ export const FunctionToolService = { const api = new OpenAPIClientAxios({ definition: yaml.load(plugin.content) as any, axiosConfigDefaults: { + adapter: (window.__TAURI__ ? adapter : ["xhr"]) as any, baseURL, headers, }, diff --git a/app/utils.ts b/app/utils.ts index 0ac5867fa..60041ba06 100644 --- a/app/utils.ts +++ b/app/utils.ts @@ -2,7 +2,9 @@ import { useEffect, useState } from "react"; import { showToast } from "./components/ui-lib"; import Locale from "./locales"; import { RequestMessage } from "./client/api"; -import { ServiceProvider } from "./constant"; +import { ServiceProvider, REQUEST_TIMEOUT_MS } from "./constant"; +import isObject from "lodash-es/isObject"; +import { fetch as tauriFetch, Body, ResponseType } from "@tauri-apps/api/http"; export function trimTopic(topic: string) { // Fix an issue where double quotes still show in the Indonesian language @@ -285,3 +287,34 @@ export function showPlugins(provider: ServiceProvider, model: string) { } return false; } + +export function fetch( + url: string, + options?: Record, +): Promise { + if (window.__TAURI__) { + const payload = options?.body || options?.data; + return tauriFetch(url, { + ...options, + body: + payload && + ({ + type: "Text", + payload, + } as any), + timeout: ((options?.timeout as number) || REQUEST_TIMEOUT_MS) / 1000, + responseType: + options?.responseType == "text" ? ResponseType.Text : ResponseType.JSON, + } as any); + } + return window.fetch(url, options); +} + +export function adapter(config: Record) { + const { baseURL, url, params, ...rest } = config; + const path = baseURL ? `${baseURL}${url}` : url; + const fetchUrl = params + ? `${path}?${new URLSearchParams(params as any).toString()}` + : path; + return fetch(fetchUrl as string, { ...rest, responseType: "text" }); +} diff --git a/package.json b/package.json index d3f062185..ca5fcc0f5 100644 --- a/package.json +++ b/package.json @@ -51,14 +51,15 @@ "zustand": "^4.3.8" }, "devDependencies": { + "@tauri-apps/api": "^1.6.0", "@tauri-apps/cli": "1.5.11", + "@types/js-yaml": "4.0.9", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.30", "@types/react": "^18.2.70", "@types/react-dom": "^18.2.7", "@types/react-katex": "^3.0.0", "@types/spark-md5": "^3.0.4", - "@types/js-yaml": "4.0.9", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.49.0", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e08925902..387584491 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -17,7 +17,7 @@ tauri-build = { version = "1.5.1", features = [] } [dependencies] serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } -tauri = { version = "1.5.4", features = [ +tauri = { version = "1.5.4", features = [ "http-all", "notification-all", "fs-all", "clipboard-all", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 120ab9b5a..78807a2c5 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -50,6 +50,11 @@ }, "notification": { "all": true + }, + "http": { + "all": true, + "request": true, + "scope": ["https://*", "http://*"] } }, "bundle": { diff --git a/yarn.lock b/yarn.lock index 5ca929baf..4979e4d99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1553,6 +1553,11 @@ dependencies: tslib "^2.4.0" +"@tauri-apps/api@^1.6.0": + version "1.6.0" + resolved "https://registry.npmjs.org/@tauri-apps/api/-/api-1.6.0.tgz#745b7e4e26782c3b2ad9510d558fa5bb2cf29186" + integrity sha512-rqI++FWClU5I2UBp4HXFvl+sBWkdigBkxnpJDQUWttNyG7IZP4FwQGhTNL5EOw0vI8i6eSAJ5frLqO7n7jbJdg== + "@tauri-apps/cli-darwin-arm64@1.5.11": version "1.5.11" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.11.tgz#a831f98f685148e46e8050dbdddbf4bcdda9ddc6"