feat: Add custom headers support
This commit is contained in:
parent
86296c96b6
commit
52f9a2953a
@ -229,6 +229,18 @@
|
||||
"label": "Custom Origin URL",
|
||||
"placeholder": "Enter Custom Origin URL"
|
||||
},
|
||||
"headers": {
|
||||
"label": "Custom Headers",
|
||||
"add": "Add Header",
|
||||
"key": {
|
||||
"label": "Header Key",
|
||||
"placeholder": "Authorization"
|
||||
},
|
||||
"value": {
|
||||
"label": "Header Value",
|
||||
"placeholder": "Bearer token"
|
||||
}
|
||||
},
|
||||
"help": "If you have connection issues with Ollama on Page Assist, you can configure a custom origin URL. To learn more about the configuration, <anchor>click here</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,18 @@
|
||||
"label": "URL Personalizada",
|
||||
"placeholder": "Ingresar URL Personalizada"
|
||||
},
|
||||
"headers": {
|
||||
"label": "Encabezados Personalizados",
|
||||
"add": "Agregar Encabezado",
|
||||
"key": {
|
||||
"label": "Clave del Encabezado",
|
||||
"placeholder": "Autorización"
|
||||
},
|
||||
"value": {
|
||||
"label": "Valor del Encabezado",
|
||||
"placeholder": "Token Bearer"
|
||||
}
|
||||
},
|
||||
"help": "Si tenes problemas de conexión con Ollama en Page Assist, podes configurar una URL de personalizada. Para saber más sobre la configuración, <anchor>click aqui</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,18 @@
|
||||
"label": "URL d'origine personnalisée",
|
||||
"placeholder": "Entrez l'URL d'origine personnalisée"
|
||||
},
|
||||
"headers": {
|
||||
"label": "En-têtes Personnalisés",
|
||||
"add": "Ajouter En-tête",
|
||||
"key": {
|
||||
"label": "Clé de l'En-tête",
|
||||
"placeholder": "Autorisation"
|
||||
},
|
||||
"value": {
|
||||
"label": "Valeur de l'En-tête",
|
||||
"placeholder": "Jeton Bearer"
|
||||
}
|
||||
},
|
||||
"help": "Si vous avez des problèmes de connexion avec OLLAMA sur Page Assist, vous pouvez configurer une URL d'origine personnalisée. Pour en savoir plus sur la configuration, <anchor>cliquez ici</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,18 @@
|
||||
"label": "URL di Origine Personalizzato",
|
||||
"placeholder": "Inserisci URL di Origine Personalizzato"
|
||||
},
|
||||
"headers": {
|
||||
"label": "Intestazioni Personalizzate",
|
||||
"add": "Aggiungi Intestazione",
|
||||
"key": {
|
||||
"label": "Chiave dell'Intestazione",
|
||||
"placeholder": "Autorizzazione"
|
||||
},
|
||||
"value": {
|
||||
"label": "Valore dell'Intestazione",
|
||||
"placeholder": "Token Bearer"
|
||||
}
|
||||
},
|
||||
"help": "Se hai problemi di connessione con Ollama su Page Assist, puoi configurare un URL di origine personalizzato. Per saperne di più sulla configurazione, <anchor>clicca qui</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -232,6 +232,18 @@
|
||||
"label": "カスタムOriginのURL",
|
||||
"placeholder": "カスタムOriginのURLを入力"
|
||||
},
|
||||
"headers": {
|
||||
"label": "カスタムヘッダー",
|
||||
"add": "ヘッダーを追加",
|
||||
"key": {
|
||||
"label": "ヘッダーキー",
|
||||
"placeholder": "認証"
|
||||
},
|
||||
"value": {
|
||||
"label": "ヘッダー値",
|
||||
"placeholder": "ベアラートークン"
|
||||
}
|
||||
},
|
||||
"help": "PageAssistでOllamaに接続の問題がある場合は、カスタムOriginのURLを設定できます。設定の詳細については、<anchor>ここをクリック</anchor>してください。"
|
||||
}
|
||||
}
|
||||
|
@ -232,6 +232,18 @@
|
||||
"label": "Custom Origin URL",
|
||||
"placeholder": "Enter Custom Origin URL"
|
||||
},
|
||||
"headers": {
|
||||
"label": "കസ്റ്റം തലക്കെട്ടുകൾ",
|
||||
"add": "തലക്കെട്ട് ചേർക്കുക",
|
||||
"key": {
|
||||
"label": "തലക്കെട്ട് കീ",
|
||||
"placeholder": "അധികൃതപെടുത്തൽ"
|
||||
},
|
||||
"value": {
|
||||
"label": "തലക്കെട്ട് മൂല്യം",
|
||||
"placeholder": "ബെയറർ ടോക്കൺ"
|
||||
}
|
||||
},
|
||||
"help": "ഏജ് അസിസ്റ്റന്റിൽ Ollama-യുമായി ബന്ധപ്പെടുമ്പോൾ ബന്ധതടസ്സം ഉണ്ടെങ്കിൽ, നിങ്ങൾക്ക് ഒരു വ്യക്തിഗത അസ്ഥിരത്വം URL കോൺഫിഗർ ചെയ്യാം. കോൺഫിഗറേഷനെക്കുറിച്ച് കൂടുതലറിയാൻ, <anchor>ഇവിടെ ക്ലിക്കുചെയ്യുക</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,18 @@
|
||||
"label": "URL de Origem Personalizada",
|
||||
"placeholder": "Insira a URL de Origem Personalizada"
|
||||
},
|
||||
"headers": {
|
||||
"label": "Cabeçalhos Personalizados",
|
||||
"add": "Adicionar Cabeçalho",
|
||||
"key": {
|
||||
"label": "Chave do Cabeçalho",
|
||||
"placeholder": "Autorização"
|
||||
},
|
||||
"value": {
|
||||
"label": "Valor do Cabeçalho",
|
||||
"placeholder": "Token Bearer"
|
||||
}
|
||||
},
|
||||
"help": "Se você tiver problemas de conexão com o Ollama no Page Assist, você pode configurar uma URL de origem personalizada. Para saber mais sobre a configuração, <anchor>clique aqui</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -230,6 +230,18 @@
|
||||
"label": "Пользовательский исходный URL",
|
||||
"placeholder": "Введите пользовательский исходный URL"
|
||||
},
|
||||
"headers": {
|
||||
"label": "Пользовательские Заголовки",
|
||||
"add": "Добавить Заголовок",
|
||||
"key": {
|
||||
"label": "Ключ Заголовка",
|
||||
"placeholder": "Авторизация"
|
||||
},
|
||||
"value": {
|
||||
"label": "Значение Заголовка",
|
||||
"placeholder": "Токен Bearer"
|
||||
}
|
||||
},
|
||||
"help": "Если у вас возникают проблемы с подключением к Ollama на странице помощника, вы можете настроить пользовательский исходный URL. Чтобы узнать больше о конфигурации, <anchor>нажмите здесь</anchor>."
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +234,18 @@
|
||||
"label": "自定义来源 URL",
|
||||
"placeholder": "输入自定义来源 URL"
|
||||
},
|
||||
"headers": {
|
||||
"label": "自定义头部",
|
||||
"add": "添加头部",
|
||||
"key": {
|
||||
"label": "头部键",
|
||||
"placeholder": "授权"
|
||||
},
|
||||
"value": {
|
||||
"label": "头部值",
|
||||
"placeholder": "承载令牌"
|
||||
}
|
||||
},
|
||||
"help": "如果您在 Page Assist 上与 Ollama 有连接问题,您可以配置自定义来源 URL。要了解更多关于配置的信息,<anchor>点击此处</anchor>。"
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +1,132 @@
|
||||
import { useStorage } from "@plasmohq/storage/hook"
|
||||
import { Input, Switch } from "antd"
|
||||
import { Divider, Input, Switch } from "antd"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { Form } from "antd"
|
||||
import React from "react"
|
||||
import {
|
||||
customOllamaHeaders,
|
||||
getRewriteUrl,
|
||||
isUrlRewriteEnabled,
|
||||
setCustomOllamaHeaders,
|
||||
setRewriteUrl,
|
||||
setUrlRewriteEnabled
|
||||
} from "@/services/app"
|
||||
import { Trash2Icon } from "lucide-react"
|
||||
import { SaveButton } from "../SaveButton"
|
||||
|
||||
export const AdvanceOllamaSettings = () => {
|
||||
const [urlRewriteEnabled, setUrlRewriteEnabled] = useStorage(
|
||||
"urlRewriteEnabled",
|
||||
false
|
||||
)
|
||||
const [form] = Form.useForm()
|
||||
const watchUrlRewriteEnabled = Form.useWatch("urlRewriteEnabled", form)
|
||||
|
||||
const fetchAdvancedData = async () => {
|
||||
const [urlRewriteEnabled, rewriteUrl, headers] = await Promise.all([
|
||||
isUrlRewriteEnabled(),
|
||||
getRewriteUrl(),
|
||||
customOllamaHeaders()
|
||||
])
|
||||
form.setFieldsValue({ urlRewriteEnabled, rewriteUrl, headers })
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
fetchAdvancedData()
|
||||
}, [])
|
||||
|
||||
const [rewriteUrl, setRewriteUrl] = useStorage(
|
||||
"rewriteUrl",
|
||||
"http://127.0.0.1:11434"
|
||||
)
|
||||
const { t } = useTranslation("settings")
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex sm:flex-row flex-col space-y-4 sm:space-y-0 sm:justify-between">
|
||||
<span className="text-gray-700 dark:text-neutral-50 ">
|
||||
{t("ollamaSettings.settings.advanced.urlRewriteEnabled.label")}
|
||||
</span>
|
||||
<div>
|
||||
<Switch
|
||||
className="mt-4 sm:mt-0"
|
||||
checked={urlRewriteEnabled}
|
||||
onChange={(checked) => setUrlRewriteEnabled(checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-4 sm:space-y-0 sm:justify-between">
|
||||
<span className="text-gray-700 dark:text-neutral-50 mb-3">
|
||||
{t("ollamaSettings.settings.advanced.rewriteUrl.label")}
|
||||
</span>
|
||||
<div>
|
||||
<Form
|
||||
onFinish={(e) => {
|
||||
const headers = e?.headers?.filter(
|
||||
(header: { key: string; value: string }) => header.key && header.value
|
||||
)
|
||||
setUrlRewriteEnabled(e.urlRewriteEnabled)
|
||||
setRewriteUrl(e.rewriteUrl)
|
||||
setCustomOllamaHeaders(headers)
|
||||
}}
|
||||
form={form}
|
||||
layout="vertical"
|
||||
className="space-y-4">
|
||||
<Form.Item
|
||||
name="urlRewriteEnabled"
|
||||
label={t("ollamaSettings.settings.advanced.urlRewriteEnabled.label")}>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
required={watchUrlRewriteEnabled}
|
||||
name="rewriteUrl"
|
||||
label={t("ollamaSettings.settings.advanced.rewriteUrl.label")}>
|
||||
<Input
|
||||
disabled={!watchUrlRewriteEnabled}
|
||||
className="w-full"
|
||||
value={rewriteUrl}
|
||||
disabled={!urlRewriteEnabled}
|
||||
placeholder={t(
|
||||
"ollamaSettings.settings.advanced.rewriteUrl.placeholder"
|
||||
)}
|
||||
onChange={(e) => setRewriteUrl(e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.List name="headers">
|
||||
{(fields, { add, remove }) => (
|
||||
<div className="flex flex-col ">
|
||||
<div className="flex justify-between items-center">
|
||||
<h3 className="text-md font-semibold">
|
||||
{t("ollamaSettings.settings.advanced.headers.label")}
|
||||
</h3>
|
||||
<button
|
||||
type="button"
|
||||
className="dark:bg-white dark:text-black text-white bg-black p-1.5 text-xs rounded-md"
|
||||
onClick={() => {
|
||||
add()
|
||||
}}>
|
||||
{t("ollamaSettings.settings.advanced.headers.add")}
|
||||
</button>
|
||||
</div>
|
||||
{fields.map((field, index) => (
|
||||
<div key={field.key} className="flex items-center w-full">
|
||||
<div className="flex-grow flex space-x-4">
|
||||
<Form.Item
|
||||
label={t(
|
||||
"ollamaSettings.settings.advanced.headers.key.label"
|
||||
)}
|
||||
name={[field.name, "key"]}
|
||||
className="flex-1 mb-0">
|
||||
<Input
|
||||
className="w-full"
|
||||
placeholder={t(
|
||||
"ollamaSettings.settings.advanced.headers.key.placeholder"
|
||||
)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t(
|
||||
"ollamaSettings.settings.advanced.headers.value.label"
|
||||
)}
|
||||
name={[field.name, "value"]}
|
||||
className="flex-1 mb-0">
|
||||
<Input
|
||||
className="w-full"
|
||||
placeholder={t(
|
||||
"ollamaSettings.settings.advanced.headers.value.placeholder"
|
||||
)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
remove(field.name)
|
||||
}}
|
||||
className="shrink-0 ml-2 text-red-500 dark:text-red-400">
|
||||
<Trash2Icon className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Form.List>
|
||||
<Divider />
|
||||
|
||||
<Form.Item className="flex justify-end">
|
||||
<SaveButton btnType="submit" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
@ -50,6 +50,14 @@ export const SettingsOllama = () => {
|
||||
className="w-full p-2 border border-gray-300 rounded-md dark:bg-[#262626] dark:text-gray-100"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end mb-3">
|
||||
<SaveButton
|
||||
onClick={() => {
|
||||
saveOllamaURL(ollamaURL)
|
||||
}}
|
||||
className="mt-2"
|
||||
/>
|
||||
</div>
|
||||
<Collapse
|
||||
size="small"
|
||||
items={[
|
||||
@ -79,15 +87,6 @@ export const SettingsOllama = () => {
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<SaveButton
|
||||
onClick={() => {
|
||||
saveOllamaURL(ollamaURL)
|
||||
}}
|
||||
className="mt-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ModelSettings />
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Embeddings, EmbeddingsParams } from "@langchain/core/embeddings"
|
||||
import type { StringWithAutocomplete } from "@langchain/core/utils/types"
|
||||
import { parseKeepAlive } from "./utils/ollama"
|
||||
import { getCustomOllamaHeaders } from "@/services/app"
|
||||
|
||||
export interface OllamaInput {
|
||||
embeddingOnly?: boolean
|
||||
@ -213,12 +214,14 @@ export class OllamaEmbeddingsPageAssist extends Embeddings {
|
||||
"http://127.0.0.1:"
|
||||
)
|
||||
}
|
||||
const customHeaders = await getCustomOllamaHeaders()
|
||||
|
||||
const response = await fetch(`${formattedBaseUrl}/api/embeddings`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...this.headers
|
||||
...this.headers,
|
||||
...customHeaders
|
||||
},
|
||||
body: JSON.stringify({
|
||||
prompt,
|
||||
|
@ -1,184 +1,189 @@
|
||||
import { IterableReadableStream } from "@langchain/core/utils/stream";
|
||||
import type { StringWithAutocomplete } from "@langchain/core/utils/types";
|
||||
import { BaseLanguageModelCallOptions } from "@langchain/core/language_models/base";
|
||||
import { IterableReadableStream } from "@langchain/core/utils/stream"
|
||||
import type { StringWithAutocomplete } from "@langchain/core/utils/types"
|
||||
import { BaseLanguageModelCallOptions } from "@langchain/core/language_models/base"
|
||||
import { getCustomOllamaHeaders } from "@/services/app"
|
||||
|
||||
export interface OllamaInput {
|
||||
embeddingOnly?: boolean;
|
||||
f16KV?: boolean;
|
||||
frequencyPenalty?: number;
|
||||
headers?: Record<string, string>;
|
||||
keepAlive?: any;
|
||||
logitsAll?: boolean;
|
||||
lowVram?: boolean;
|
||||
mainGpu?: number;
|
||||
model?: string;
|
||||
baseUrl?: string;
|
||||
mirostat?: number;
|
||||
mirostatEta?: number;
|
||||
mirostatTau?: number;
|
||||
numBatch?: number;
|
||||
numCtx?: number;
|
||||
numGpu?: number;
|
||||
numGqa?: number;
|
||||
numKeep?: number;
|
||||
numPredict?: number;
|
||||
numThread?: number;
|
||||
penalizeNewline?: boolean;
|
||||
presencePenalty?: number;
|
||||
repeatLastN?: number;
|
||||
repeatPenalty?: number;
|
||||
ropeFrequencyBase?: number;
|
||||
ropeFrequencyScale?: number;
|
||||
temperature?: number;
|
||||
stop?: string[];
|
||||
tfsZ?: number;
|
||||
topK?: number;
|
||||
topP?: number;
|
||||
typicalP?: number;
|
||||
useMLock?: boolean;
|
||||
useMMap?: boolean;
|
||||
vocabOnly?: boolean;
|
||||
seed?: number;
|
||||
format?: StringWithAutocomplete<"json">;
|
||||
embeddingOnly?: boolean
|
||||
f16KV?: boolean
|
||||
frequencyPenalty?: number
|
||||
headers?: Record<string, string>
|
||||
keepAlive?: any
|
||||
logitsAll?: boolean
|
||||
lowVram?: boolean
|
||||
mainGpu?: number
|
||||
model?: string
|
||||
baseUrl?: string
|
||||
mirostat?: number
|
||||
mirostatEta?: number
|
||||
mirostatTau?: number
|
||||
numBatch?: number
|
||||
numCtx?: number
|
||||
numGpu?: number
|
||||
numGqa?: number
|
||||
numKeep?: number
|
||||
numPredict?: number
|
||||
numThread?: number
|
||||
penalizeNewline?: boolean
|
||||
presencePenalty?: number
|
||||
repeatLastN?: number
|
||||
repeatPenalty?: number
|
||||
ropeFrequencyBase?: number
|
||||
ropeFrequencyScale?: number
|
||||
temperature?: number
|
||||
stop?: string[]
|
||||
tfsZ?: number
|
||||
topK?: number
|
||||
topP?: number
|
||||
typicalP?: number
|
||||
useMLock?: boolean
|
||||
useMMap?: boolean
|
||||
vocabOnly?: boolean
|
||||
seed?: number
|
||||
format?: StringWithAutocomplete<"json">
|
||||
}
|
||||
|
||||
export interface OllamaRequestParams {
|
||||
model: string;
|
||||
format?: StringWithAutocomplete<"json">;
|
||||
images?: string[];
|
||||
model: string
|
||||
format?: StringWithAutocomplete<"json">
|
||||
images?: string[]
|
||||
options: {
|
||||
embedding_only?: boolean;
|
||||
f16_kv?: boolean;
|
||||
frequency_penalty?: number;
|
||||
logits_all?: boolean;
|
||||
low_vram?: boolean;
|
||||
main_gpu?: number;
|
||||
mirostat?: number;
|
||||
mirostat_eta?: number;
|
||||
mirostat_tau?: number;
|
||||
num_batch?: number;
|
||||
num_ctx?: number;
|
||||
num_gpu?: number;
|
||||
num_gqa?: number;
|
||||
num_keep?: number;
|
||||
num_thread?: number;
|
||||
num_predict?: number;
|
||||
penalize_newline?: boolean;
|
||||
presence_penalty?: number;
|
||||
repeat_last_n?: number;
|
||||
repeat_penalty?: number;
|
||||
rope_frequency_base?: number;
|
||||
rope_frequency_scale?: number;
|
||||
temperature?: number;
|
||||
stop?: string[];
|
||||
tfs_z?: number;
|
||||
top_k?: number;
|
||||
top_p?: number;
|
||||
typical_p?: number;
|
||||
use_mlock?: boolean;
|
||||
use_mmap?: boolean;
|
||||
vocab_only?: boolean;
|
||||
};
|
||||
embedding_only?: boolean
|
||||
f16_kv?: boolean
|
||||
frequency_penalty?: number
|
||||
logits_all?: boolean
|
||||
low_vram?: boolean
|
||||
main_gpu?: number
|
||||
mirostat?: number
|
||||
mirostat_eta?: number
|
||||
mirostat_tau?: number
|
||||
num_batch?: number
|
||||
num_ctx?: number
|
||||
num_gpu?: number
|
||||
num_gqa?: number
|
||||
num_keep?: number
|
||||
num_thread?: number
|
||||
num_predict?: number
|
||||
penalize_newline?: boolean
|
||||
presence_penalty?: number
|
||||
repeat_last_n?: number
|
||||
repeat_penalty?: number
|
||||
rope_frequency_base?: number
|
||||
rope_frequency_scale?: number
|
||||
temperature?: number
|
||||
stop?: string[]
|
||||
tfs_z?: number
|
||||
top_k?: number
|
||||
top_p?: number
|
||||
typical_p?: number
|
||||
use_mlock?: boolean
|
||||
use_mmap?: boolean
|
||||
vocab_only?: boolean
|
||||
}
|
||||
}
|
||||
|
||||
export type OllamaMessage = {
|
||||
role: StringWithAutocomplete<"user" | "assistant" | "system">;
|
||||
content: string;
|
||||
images?: string[];
|
||||
};
|
||||
role: StringWithAutocomplete<"user" | "assistant" | "system">
|
||||
content: string
|
||||
images?: string[]
|
||||
}
|
||||
|
||||
export interface OllamaGenerateRequestParams extends OllamaRequestParams {
|
||||
prompt: string;
|
||||
prompt: string
|
||||
}
|
||||
|
||||
export interface OllamaChatRequestParams extends OllamaRequestParams {
|
||||
messages: OllamaMessage[];
|
||||
messages: OllamaMessage[]
|
||||
}
|
||||
|
||||
export type BaseOllamaGenerationChunk = {
|
||||
model: string;
|
||||
created_at: string;
|
||||
done: boolean;
|
||||
total_duration?: number;
|
||||
load_duration?: number;
|
||||
prompt_eval_count?: number;
|
||||
prompt_eval_duration?: number;
|
||||
eval_count?: number;
|
||||
eval_duration?: number;
|
||||
};
|
||||
model: string
|
||||
created_at: string
|
||||
done: boolean
|
||||
total_duration?: number
|
||||
load_duration?: number
|
||||
prompt_eval_count?: number
|
||||
prompt_eval_duration?: number
|
||||
eval_count?: number
|
||||
eval_duration?: number
|
||||
}
|
||||
|
||||
export type OllamaGenerationChunk = BaseOllamaGenerationChunk & {
|
||||
response: string;
|
||||
};
|
||||
response: string
|
||||
}
|
||||
|
||||
export type OllamaChatGenerationChunk = BaseOllamaGenerationChunk & {
|
||||
message: OllamaMessage;
|
||||
};
|
||||
message: OllamaMessage
|
||||
}
|
||||
|
||||
export type OllamaCallOptions = BaseLanguageModelCallOptions & {
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
headers?: Record<string, string>
|
||||
}
|
||||
|
||||
async function* createOllamaStream(
|
||||
url: string,
|
||||
params: OllamaRequestParams,
|
||||
options: OllamaCallOptions
|
||||
) {
|
||||
let formattedUrl = url;
|
||||
let formattedUrl = url
|
||||
if (formattedUrl.startsWith("http://localhost:")) {
|
||||
// Node 18 has issues with resolving "localhost"
|
||||
// See https://github.com/node-fetch/node-fetch/issues/1624
|
||||
formattedUrl = formattedUrl.replace(
|
||||
"http://localhost:",
|
||||
"http://127.0.0.1:"
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const customHeaders = await getCustomOllamaHeaders()
|
||||
|
||||
const response = await fetch(formattedUrl, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(params),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
...customHeaders
|
||||
},
|
||||
signal: options.signal,
|
||||
});
|
||||
signal: options.signal
|
||||
})
|
||||
if (!response.ok) {
|
||||
let error;
|
||||
const responseText = await response.text();
|
||||
let error
|
||||
const responseText = await response.text()
|
||||
try {
|
||||
const json = JSON.parse(responseText);
|
||||
const json = JSON.parse(responseText)
|
||||
error = new Error(
|
||||
`Ollama call failed with status code ${response.status}: ${json.error}`
|
||||
);
|
||||
)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
error = new Error(
|
||||
`Ollama call failed with status code ${response.status}: ${responseText}`
|
||||
);
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(error as any).response = response;
|
||||
throw error;
|
||||
;(error as any).response = response
|
||||
throw error
|
||||
}
|
||||
if (!response.body) {
|
||||
throw new Error(
|
||||
"Could not begin Ollama stream. Please check the given URL and try again."
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const stream = IterableReadableStream.fromReadableStream(response.body);
|
||||
const stream = IterableReadableStream.fromReadableStream(response.body)
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
let extra = "";
|
||||
const decoder = new TextDecoder()
|
||||
let extra = ""
|
||||
for await (const chunk of stream) {
|
||||
const decoded = extra + decoder.decode(chunk);
|
||||
const lines = decoded.split("\n");
|
||||
extra = lines.pop() || "";
|
||||
const decoded = extra + decoder.decode(chunk)
|
||||
const lines = decoded.split("\n")
|
||||
extra = lines.pop() || ""
|
||||
for (const line of lines) {
|
||||
try {
|
||||
yield JSON.parse(line);
|
||||
yield JSON.parse(line)
|
||||
} catch (e) {
|
||||
console.warn(`Received a non-JSON parseable chunk: ${line}`);
|
||||
console.warn(`Received a non-JSON parseable chunk: ${line}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -189,7 +194,7 @@ export async function* createOllamaGenerateStream(
|
||||
params: OllamaGenerateRequestParams,
|
||||
options: OllamaCallOptions
|
||||
): AsyncGenerator<OllamaGenerationChunk> {
|
||||
yield* createOllamaStream(`${baseUrl}/api/generate`, params, options);
|
||||
yield* createOllamaStream(`${baseUrl}/api/generate`, params, options)
|
||||
}
|
||||
|
||||
export async function* createOllamaChatStream(
|
||||
@ -197,10 +202,9 @@ export async function* createOllamaChatStream(
|
||||
params: OllamaChatRequestParams,
|
||||
options: OllamaCallOptions
|
||||
): AsyncGenerator<OllamaChatGenerationChunk> {
|
||||
yield* createOllamaStream(`${baseUrl}/api/chat`, params, options);
|
||||
yield* createOllamaStream(`${baseUrl}/api/chat`, params, options)
|
||||
}
|
||||
|
||||
|
||||
export const parseKeepAlive = (keepAlive: any) => {
|
||||
if (keepAlive === "-1") {
|
||||
return -1
|
||||
|
@ -5,10 +5,10 @@ const DEFAULT_URL_REWRITE_URL = "http://127.0.0.1:11434"
|
||||
|
||||
export const isUrlRewriteEnabled = async () => {
|
||||
const enabled = await storage.get<boolean | undefined>("urlRewriteEnabled")
|
||||
return enabled
|
||||
return enabled ?? false
|
||||
}
|
||||
export const setUrlRewriteEnabled = async (enabled: boolean) => {
|
||||
await storage.set("urlRewriteEnabled", enabled ? "true" : "false")
|
||||
await storage.set("urlRewriteEnabled", enabled)
|
||||
}
|
||||
|
||||
export const getRewriteUrl = async () => {
|
||||
@ -35,12 +35,10 @@ export const getAdvancedOllamaSettings = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const copilotResumeLastChat = async () => {
|
||||
return await storage.get<boolean>("copilotResumeLastChat")
|
||||
}
|
||||
|
||||
|
||||
export const defaultSidebarOpen = async () => {
|
||||
const sidebarOpen = await storage.get("sidebarOpen")
|
||||
if (!sidebarOpen || sidebarOpen === "") {
|
||||
@ -49,7 +47,36 @@ export const defaultSidebarOpen = async () => {
|
||||
return sidebarOpen
|
||||
}
|
||||
|
||||
|
||||
export const setSidebarOpen = async (sidebarOpen: string) => {
|
||||
await storage.set("sidebarOpen", sidebarOpen)
|
||||
}
|
||||
|
||||
export const customOllamaHeaders = async (): Promise<
|
||||
{ key: string; value: string }[]
|
||||
> => {
|
||||
const headers = await storage.get<
|
||||
{ key: string; value: string }[] | undefined
|
||||
>("customOllamaHeaders")
|
||||
if (!headers) {
|
||||
return []
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
export const setCustomOllamaHeaders = async (headers: string[]) => {
|
||||
await storage.set("customOllamaHeaders", headers)
|
||||
}
|
||||
|
||||
export const getCustomOllamaHeaders = async (): Promise<
|
||||
Record<string, string>
|
||||
> => {
|
||||
const headers = await customOllamaHeaders()
|
||||
|
||||
const headerMap: Record<string, string> = {}
|
||||
|
||||
for (const header of headers) {
|
||||
headerMap[header.key] = header.value
|
||||
}
|
||||
|
||||
return headerMap
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user