2749 ollama client auth token (#3005)
* ollama auth token provision * auth token provision * ollama auth provision * ollama auth token * ollama auth provision * token input field css fix * Fix provider handler not using key sensible fallback to not break existing installs re-order of input fields null-check for API key and header optional insert on request linting * apply header and auth to agent invocations * upgrading to ollama 5.10 for passing headers to constructor * rename Auth systemSetting key to be more descriptive linting and copy * remove untracked files + update gitignore * remove debug * patch lockfile --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
parent
3390ccf4b1
commit
3fd0fe8fc5
@ -42,6 +42,7 @@ GID='1000'
|
|||||||
# OLLAMA_BASE_PATH='http://host.docker.internal:11434'
|
# OLLAMA_BASE_PATH='http://host.docker.internal:11434'
|
||||||
# OLLAMA_MODEL_PREF='llama2'
|
# OLLAMA_MODEL_PREF='llama2'
|
||||||
# OLLAMA_MODEL_TOKEN_LIMIT=4096
|
# OLLAMA_MODEL_TOKEN_LIMIT=4096
|
||||||
|
# OLLAMA_AUTH_TOKEN='your-ollama-auth-token-here (optional, only for ollama running behind auth - Bearer token)'
|
||||||
|
|
||||||
# LLM_PROVIDER='togetherai'
|
# LLM_PROVIDER='togetherai'
|
||||||
# TOGETHER_AI_API_KEY='my-together-ai-key'
|
# TOGETHER_AI_API_KEY='my-together-ai-key'
|
||||||
|
|||||||
@ -11,12 +11,15 @@ export default function OllamaLLMOptions({ settings }) {
|
|||||||
autoDetecting: loading,
|
autoDetecting: loading,
|
||||||
basePath,
|
basePath,
|
||||||
basePathValue,
|
basePathValue,
|
||||||
|
authToken,
|
||||||
|
authTokenValue,
|
||||||
showAdvancedControls,
|
showAdvancedControls,
|
||||||
setShowAdvancedControls,
|
setShowAdvancedControls,
|
||||||
handleAutoDetectClick,
|
handleAutoDetectClick,
|
||||||
} = useProviderEndpointAutoDiscovery({
|
} = useProviderEndpointAutoDiscovery({
|
||||||
provider: "ollama",
|
provider: "ollama",
|
||||||
initialBasePath: settings?.OllamaLLMBasePath,
|
initialBasePath: settings?.OllamaLLMBasePath,
|
||||||
|
initialAuthToken: settings?.OllamaLLMAuthToken,
|
||||||
ENDPOINTS: OLLAMA_COMMON_URLS,
|
ENDPOINTS: OLLAMA_COMMON_URLS,
|
||||||
});
|
});
|
||||||
const [performanceMode, setPerformanceMode] = useState(
|
const [performanceMode, setPerformanceMode] = useState(
|
||||||
@ -32,6 +35,7 @@ export default function OllamaLLMOptions({ settings }) {
|
|||||||
<OllamaLLMModelSelection
|
<OllamaLLMModelSelection
|
||||||
settings={settings}
|
settings={settings}
|
||||||
basePath={basePath.value}
|
basePath={basePath.value}
|
||||||
|
authToken={authToken.value}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-col w-60">
|
<div className="flex flex-col w-60">
|
||||||
<label className="text-white text-sm font-semibold block mb-2">
|
<label className="text-white text-sm font-semibold block mb-2">
|
||||||
@ -73,120 +77,146 @@ export default function OllamaLLMOptions({ settings }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div hidden={!showAdvancedControls}>
|
<div hidden={!showAdvancedControls}>
|
||||||
<div className="w-full flex items-start gap-4">
|
<div className="flex flex-col">
|
||||||
<div className="flex flex-col w-60">
|
<div className="w-full flex items-start gap-4">
|
||||||
<div className="flex justify-between items-center mb-2">
|
<div className="flex flex-col w-60">
|
||||||
<label className="text-white text-sm font-semibold">
|
<div className="flex justify-between items-center mb-2">
|
||||||
Ollama Base URL
|
<label className="text-white text-sm font-semibold">
|
||||||
</label>
|
Ollama Base URL
|
||||||
{loading ? (
|
</label>
|
||||||
<PreLoader size="6" />
|
{loading ? (
|
||||||
) : (
|
<PreLoader size="6" />
|
||||||
<>
|
) : (
|
||||||
{!basePathValue.value && (
|
<>
|
||||||
<button
|
{!basePathValue.value && (
|
||||||
onClick={handleAutoDetectClick}
|
<button
|
||||||
className="bg-primary-button text-xs font-medium px-2 py-1 rounded-lg hover:bg-secondary hover:text-white shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
|
onClick={handleAutoDetectClick}
|
||||||
>
|
className="bg-primary-button text-xs font-medium px-2 py-1 rounded-lg hover:bg-secondary hover:text-white shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
|
||||||
Auto-Detect
|
>
|
||||||
</button>
|
Auto-Detect
|
||||||
)}
|
</button>
|
||||||
</>
|
)}
|
||||||
)}
|
</>
|
||||||
</div>
|
)}
|
||||||
<input
|
</div>
|
||||||
type="url"
|
<input
|
||||||
name="OllamaLLMBasePath"
|
type="url"
|
||||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
name="OllamaLLMBasePath"
|
||||||
placeholder="http://127.0.0.1:11434"
|
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||||
value={basePathValue.value}
|
placeholder="http://127.0.0.1:11434"
|
||||||
required={true}
|
value={basePathValue.value}
|
||||||
autoComplete="off"
|
required={true}
|
||||||
spellCheck={false}
|
autoComplete="off"
|
||||||
onChange={basePath.onChange}
|
spellCheck={false}
|
||||||
onBlur={basePath.onBlur}
|
onChange={basePath.onChange}
|
||||||
/>
|
onBlur={basePath.onBlur}
|
||||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
|
||||||
Enter the URL where Ollama is running.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col w-60">
|
|
||||||
<label className="text-white text-sm font-semibold block mb-2">
|
|
||||||
Ollama Keep Alive
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
name="OllamaLLMKeepAliveSeconds"
|
|
||||||
required={true}
|
|
||||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
|
||||||
defaultValue={settings?.OllamaLLMKeepAliveSeconds ?? "300"}
|
|
||||||
>
|
|
||||||
<option value="0">No cache</option>
|
|
||||||
<option value="300">5 minutes</option>
|
|
||||||
<option value="3600">1 hour</option>
|
|
||||||
<option value="-1">Forever</option>
|
|
||||||
</select>
|
|
||||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
|
||||||
Choose how long Ollama should keep your model in memory before
|
|
||||||
unloading.
|
|
||||||
<a
|
|
||||||
className="underline text-blue-300"
|
|
||||||
href="https://github.com/ollama/ollama/blob/main/docs/faq.md#how-do-i-keep-a-model-loaded-in-memory-or-make-it-unload-immediately"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Learn more →
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col w-60">
|
|
||||||
<label className="text-white text-sm font-semibold mb-2 flex items-center">
|
|
||||||
Performance Mode
|
|
||||||
<Info
|
|
||||||
size={16}
|
|
||||||
className="ml-2 text-white"
|
|
||||||
data-tooltip-id="performance-mode-tooltip"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
||||||
<select
|
Enter the URL where Ollama is running.
|
||||||
name="OllamaLLMPerformanceMode"
|
|
||||||
required={true}
|
|
||||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
|
||||||
value={performanceMode}
|
|
||||||
onChange={(e) => setPerformanceMode(e.target.value)}
|
|
||||||
>
|
|
||||||
<option value="base">Base (Default)</option>
|
|
||||||
<option value="maximum">Maximum</option>
|
|
||||||
</select>
|
|
||||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
|
||||||
Choose the performance mode for the Ollama model.
|
|
||||||
</p>
|
|
||||||
<Tooltip
|
|
||||||
id="performance-mode-tooltip"
|
|
||||||
place="bottom"
|
|
||||||
className="tooltip !text-xs max-w-xs"
|
|
||||||
>
|
|
||||||
<p className="text-red-500">
|
|
||||||
<strong>Note:</strong> Be careful with the Maximum mode. It may
|
|
||||||
increase resource usage significantly.
|
|
||||||
</p>
|
</p>
|
||||||
<br />
|
</div>
|
||||||
<p>
|
<div className="flex flex-col w-60">
|
||||||
<strong>Base:</strong> Ollama automatically limits the context
|
<label className="text-white text-sm font-semibold mb-2 flex items-center">
|
||||||
to 2048 tokens, keeping resources usage low while maintaining
|
Performance Mode
|
||||||
good performance. Suitable for most users and models.
|
<Info
|
||||||
|
size={16}
|
||||||
|
className="ml-2 text-white"
|
||||||
|
data-tooltip-id="performance-mode-tooltip"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="OllamaLLMPerformanceMode"
|
||||||
|
required={true}
|
||||||
|
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||||
|
value={performanceMode}
|
||||||
|
onChange={(e) => setPerformanceMode(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="base">Base (Default)</option>
|
||||||
|
<option value="maximum">Maximum</option>
|
||||||
|
</select>
|
||||||
|
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
||||||
|
Choose the performance mode for the Ollama model.
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<Tooltip
|
||||||
<p>
|
id="performance-mode-tooltip"
|
||||||
<strong>Maximum:</strong> Uses the full context window (up to
|
place="bottom"
|
||||||
Max Tokens). Will result in increased resource usage but allows
|
className="tooltip !text-xs max-w-xs"
|
||||||
for larger context conversations. <br />
|
>
|
||||||
|
<p className="text-red-500">
|
||||||
|
<strong>Note:</strong> Be careful with the Maximum mode. It
|
||||||
|
may increase resource usage significantly.
|
||||||
|
</p>
|
||||||
<br />
|
<br />
|
||||||
This is not recommended for most users.
|
<p>
|
||||||
|
<strong>Base:</strong> Ollama automatically limits the context
|
||||||
|
to 2048 tokens, keeping resources usage low while maintaining
|
||||||
|
good performance. Suitable for most users and models.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
<strong>Maximum:</strong> Uses the full context window (up to
|
||||||
|
Max Tokens). Will result in increased resource usage but
|
||||||
|
allows for larger context conversations. <br />
|
||||||
|
<br />
|
||||||
|
This is not recommended for most users.
|
||||||
|
</p>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<label className="text-white text-sm font-semibold block mb-2">
|
||||||
|
Ollama Keep Alive
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
name="OllamaLLMKeepAliveSeconds"
|
||||||
|
required={true}
|
||||||
|
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||||
|
defaultValue={settings?.OllamaLLMKeepAliveSeconds ?? "300"}
|
||||||
|
>
|
||||||
|
<option value="0">No cache</option>
|
||||||
|
<option value="300">5 minutes</option>
|
||||||
|
<option value="3600">1 hour</option>
|
||||||
|
<option value="-1">Forever</option>
|
||||||
|
</select>
|
||||||
|
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
||||||
|
Choose how long Ollama should keep your model in memory before
|
||||||
|
unloading.
|
||||||
|
<a
|
||||||
|
className="underline text-blue-300"
|
||||||
|
href="https://github.com/ollama/ollama/blob/main/docs/faq.md#how-do-i-keep-a-model-loaded-in-memory-or-make-it-unload-immediately"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
Learn more →
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</Tooltip>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full flex items-start gap-4">
|
||||||
|
<div className="flex flex-col w-100">
|
||||||
|
<label className="text-white text-sm font-semibold">
|
||||||
|
Auth Token
|
||||||
|
</label>
|
||||||
|
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
||||||
|
Enter a <code>Bearer</code> Auth Token for interacting with your
|
||||||
|
Ollama server.
|
||||||
|
<br />
|
||||||
|
Used <b>only</b> if running Ollama behind an authentication
|
||||||
|
server.
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="OllamaLLMAuthToken"
|
||||||
|
className="border-none bg-theme-settings-input-bg mt-2 text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg outline-none block w-full p-2.5"
|
||||||
|
placeholder="Ollama Auth Token"
|
||||||
|
value={authTokenValue.value}
|
||||||
|
onChange={authToken.onChange}
|
||||||
|
onBlur={authToken.onBlur}
|
||||||
|
required={false}
|
||||||
|
autoComplete="off"
|
||||||
|
spellCheck={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -194,7 +224,11 @@ export default function OllamaLLMOptions({ settings }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function OllamaLLMModelSelection({ settings, basePath = null }) {
|
function OllamaLLMModelSelection({
|
||||||
|
settings,
|
||||||
|
basePath = null,
|
||||||
|
authToken = null,
|
||||||
|
}) {
|
||||||
const [customModels, setCustomModels] = useState([]);
|
const [customModels, setCustomModels] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
@ -207,7 +241,11 @@ function OllamaLLMModelSelection({ settings, basePath = null }) {
|
|||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const { models } = await System.customModels("ollama", null, basePath);
|
const { models } = await System.customModels(
|
||||||
|
"ollama",
|
||||||
|
authToken,
|
||||||
|
basePath
|
||||||
|
);
|
||||||
setCustomModels(models || []);
|
setCustomModels(models || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch custom models:", error);
|
console.error("Failed to fetch custom models:", error);
|
||||||
@ -216,7 +254,7 @@ function OllamaLLMModelSelection({ settings, basePath = null }) {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
findCustomModels();
|
findCustomModels();
|
||||||
}, [basePath]);
|
}, [basePath, authToken]);
|
||||||
|
|
||||||
if (loading || customModels.length == 0) {
|
if (loading || customModels.length == 0) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -5,11 +5,15 @@ import showToast from "@/utils/toast";
|
|||||||
export default function useProviderEndpointAutoDiscovery({
|
export default function useProviderEndpointAutoDiscovery({
|
||||||
provider = null,
|
provider = null,
|
||||||
initialBasePath = "",
|
initialBasePath = "",
|
||||||
|
initialAuthToken = null,
|
||||||
ENDPOINTS = [],
|
ENDPOINTS = [],
|
||||||
}) {
|
}) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [basePath, setBasePath] = useState(initialBasePath);
|
const [basePath, setBasePath] = useState(initialBasePath);
|
||||||
const [basePathValue, setBasePathValue] = useState(initialBasePath);
|
const [basePathValue, setBasePathValue] = useState(initialBasePath);
|
||||||
|
|
||||||
|
const [authToken, setAuthToken] = useState(initialAuthToken);
|
||||||
|
const [authTokenValue, setAuthTokenValue] = useState(initialAuthToken);
|
||||||
const [autoDetectAttempted, setAutoDetectAttempted] = useState(false);
|
const [autoDetectAttempted, setAutoDetectAttempted] = useState(false);
|
||||||
const [showAdvancedControls, setShowAdvancedControls] = useState(true);
|
const [showAdvancedControls, setShowAdvancedControls] = useState(true);
|
||||||
|
|
||||||
@ -20,7 +24,7 @@ export default function useProviderEndpointAutoDiscovery({
|
|||||||
ENDPOINTS.forEach((endpoint) => {
|
ENDPOINTS.forEach((endpoint) => {
|
||||||
possibleEndpoints.push(
|
possibleEndpoints.push(
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
System.customModels(provider, null, endpoint, 2_000)
|
System.customModels(provider, authTokenValue, endpoint, 2_000)
|
||||||
.then((results) => {
|
.then((results) => {
|
||||||
if (!results?.models || results.models.length === 0)
|
if (!results?.models || results.models.length === 0)
|
||||||
throw new Error("No models");
|
throw new Error("No models");
|
||||||
@ -74,9 +78,18 @@ export default function useProviderEndpointAutoDiscovery({
|
|||||||
setBasePath(basePathValue);
|
setBasePath(basePathValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleAuthTokenChange(e) {
|
||||||
|
const value = e.target.value;
|
||||||
|
setAuthTokenValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAuthTokenBlur() {
|
||||||
|
setAuthToken(authTokenValue);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!initialBasePath && !autoDetectAttempted) autoDetect(true);
|
if (!initialBasePath && !autoDetectAttempted) autoDetect(true);
|
||||||
}, [initialBasePath, autoDetectAttempted]);
|
}, [initialBasePath, initialAuthToken, autoDetectAttempted]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
autoDetecting: loading,
|
autoDetecting: loading,
|
||||||
@ -93,6 +106,16 @@ export default function useProviderEndpointAutoDiscovery({
|
|||||||
value: basePathValue,
|
value: basePathValue,
|
||||||
set: setBasePathValue,
|
set: setBasePathValue,
|
||||||
},
|
},
|
||||||
|
authToken: {
|
||||||
|
value: authToken,
|
||||||
|
set: setAuthTokenValue,
|
||||||
|
onChange: handleAuthTokenChange,
|
||||||
|
onBlur: handleAuthTokenBlur,
|
||||||
|
},
|
||||||
|
authTokenValue: {
|
||||||
|
value: authTokenValue,
|
||||||
|
set: setAuthTokenValue,
|
||||||
|
},
|
||||||
handleAutoDetectClick,
|
handleAutoDetectClick,
|
||||||
runAutoDetect: autoDetect,
|
runAutoDetect: autoDetect,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -39,6 +39,7 @@ SIG_SALT='salt' # Please generate random string at least 32 chars long.
|
|||||||
# OLLAMA_BASE_PATH='http://host.docker.internal:11434'
|
# OLLAMA_BASE_PATH='http://host.docker.internal:11434'
|
||||||
# OLLAMA_MODEL_PREF='llama2'
|
# OLLAMA_MODEL_PREF='llama2'
|
||||||
# OLLAMA_MODEL_TOKEN_LIMIT=4096
|
# OLLAMA_MODEL_TOKEN_LIMIT=4096
|
||||||
|
# OLLAMA_AUTH_TOKEN='your-ollama-auth-token-here (optional, only for ollama running behind auth - Bearer token)'
|
||||||
|
|
||||||
# LLM_PROVIDER='togetherai'
|
# LLM_PROVIDER='togetherai'
|
||||||
# TOGETHER_AI_API_KEY='my-together-ai-key'
|
# TOGETHER_AI_API_KEY='my-together-ai-key'
|
||||||
|
|||||||
@ -471,6 +471,7 @@ const SystemSettings = {
|
|||||||
OllamaLLMTokenLimit: process.env.OLLAMA_MODEL_TOKEN_LIMIT,
|
OllamaLLMTokenLimit: process.env.OLLAMA_MODEL_TOKEN_LIMIT,
|
||||||
OllamaLLMKeepAliveSeconds: process.env.OLLAMA_KEEP_ALIVE_TIMEOUT ?? 300,
|
OllamaLLMKeepAliveSeconds: process.env.OLLAMA_KEEP_ALIVE_TIMEOUT ?? 300,
|
||||||
OllamaLLMPerformanceMode: process.env.OLLAMA_PERFORMANCE_MODE ?? "base",
|
OllamaLLMPerformanceMode: process.env.OLLAMA_PERFORMANCE_MODE ?? "base",
|
||||||
|
OllamaLLMAuthToken: process.env.OLLAMA_AUTH_TOKEN ?? null,
|
||||||
|
|
||||||
// Novita LLM Keys
|
// Novita LLM Keys
|
||||||
NovitaLLMApiKey: !!process.env.NOVITA_LLM_API_KEY,
|
NovitaLLMApiKey: !!process.env.NOVITA_LLM_API_KEY,
|
||||||
|
|||||||
@ -63,7 +63,7 @@
|
|||||||
"mssql": "^10.0.2",
|
"mssql": "^10.0.2",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
"mysql2": "^3.9.8",
|
"mysql2": "^3.9.8",
|
||||||
"ollama": "^0.5.0",
|
"ollama": "^0.5.10",
|
||||||
"openai": "4.38.5",
|
"openai": "4.38.5",
|
||||||
"pg": "^8.11.5",
|
"pg": "^8.11.5",
|
||||||
"pinecone-client": "^1.1.0",
|
"pinecone-client": "^1.1.0",
|
||||||
@ -97,4 +97,4 @@
|
|||||||
"nodemon": "^2.0.22",
|
"nodemon": "^2.0.22",
|
||||||
"prettier": "^3.0.3"
|
"prettier": "^3.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3
server/storage/models/.gitignore
vendored
3
server/storage/models/.gitignore
vendored
@ -7,4 +7,5 @@ novita
|
|||||||
mixedbread-ai*
|
mixedbread-ai*
|
||||||
gemini
|
gemini
|
||||||
togetherAi
|
togetherAi
|
||||||
tesseract
|
tesseract
|
||||||
|
ppio
|
||||||
@ -15,6 +15,7 @@ class OllamaAILLM {
|
|||||||
if (!process.env.OLLAMA_BASE_PATH)
|
if (!process.env.OLLAMA_BASE_PATH)
|
||||||
throw new Error("No Ollama Base Path was set.");
|
throw new Error("No Ollama Base Path was set.");
|
||||||
|
|
||||||
|
this.authToken = process.env.OLLAMA_AUTH_TOKEN;
|
||||||
this.basePath = process.env.OLLAMA_BASE_PATH;
|
this.basePath = process.env.OLLAMA_BASE_PATH;
|
||||||
this.model = modelPreference || process.env.OLLAMA_MODEL_PREF;
|
this.model = modelPreference || process.env.OLLAMA_MODEL_PREF;
|
||||||
this.performanceMode = process.env.OLLAMA_PERFORMANCE_MODE || "base";
|
this.performanceMode = process.env.OLLAMA_PERFORMANCE_MODE || "base";
|
||||||
@ -27,7 +28,10 @@ class OllamaAILLM {
|
|||||||
user: this.promptWindowLimit() * 0.7,
|
user: this.promptWindowLimit() * 0.7,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.client = new Ollama({ host: this.basePath });
|
const headers = this.authToken
|
||||||
|
? { Authorization: `Bearer ${this.authToken}` }
|
||||||
|
: {};
|
||||||
|
this.client = new Ollama({ host: this.basePath, headers: headers });
|
||||||
this.embedder = embedder ?? new NativeEmbedder();
|
this.embedder = embedder ?? new NativeEmbedder();
|
||||||
this.defaultTemp = 0.7;
|
this.defaultTemp = 0.7;
|
||||||
this.#log(
|
this.#log(
|
||||||
@ -273,9 +277,8 @@ class OllamaAILLM {
|
|||||||
type: "textResponseChunk",
|
type: "textResponseChunk",
|
||||||
textResponse: "",
|
textResponse: "",
|
||||||
close: true,
|
close: true,
|
||||||
error: `Ollama:streaming - could not stream chat. ${
|
error: `Ollama:streaming - could not stream chat. ${error?.cause ?? error.message
|
||||||
error?.cause ?? error.message
|
}`,
|
||||||
}`,
|
|
||||||
});
|
});
|
||||||
response.removeListener("close", handleAbort);
|
response.removeListener("close", handleAbort);
|
||||||
stream?.endMeasurement(usage);
|
stream?.endMeasurement(usage);
|
||||||
|
|||||||
@ -16,7 +16,13 @@ class OllamaProvider extends InheritMultiple([Provider, UnTooled]) {
|
|||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
super();
|
super();
|
||||||
this._client = new Ollama({ host: process.env.OLLAMA_BASE_PATH });
|
const headers = process.env.OLLAMA_AUTH_TOKEN
|
||||||
|
? { Authorization: `Bearer ${process.env.OLLAMA_AUTH_TOKEN}` }
|
||||||
|
: {};
|
||||||
|
this._client = new Ollama({
|
||||||
|
host: process.env.OLLAMA_BASE_PATH,
|
||||||
|
headers: headers,
|
||||||
|
});
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.verbose = true;
|
this.verbose = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ async function getCustomModels(provider = "", apiKey = null, basePath = null) {
|
|||||||
case "localai":
|
case "localai":
|
||||||
return await localAIModels(basePath, apiKey);
|
return await localAIModels(basePath, apiKey);
|
||||||
case "ollama":
|
case "ollama":
|
||||||
return await ollamaAIModels(basePath);
|
return await ollamaAIModels(basePath, apiKey);
|
||||||
case "togetherai":
|
case "togetherai":
|
||||||
return await getTogetherAiModels(apiKey);
|
return await getTogetherAiModels(apiKey);
|
||||||
case "fireworksai":
|
case "fireworksai":
|
||||||
@ -292,7 +292,7 @@ async function getKoboldCPPModels(basePath = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ollamaAIModels(basePath = null) {
|
async function ollamaAIModels(basePath = null, _authToken = null) {
|
||||||
let url;
|
let url;
|
||||||
try {
|
try {
|
||||||
let urlPath = basePath ?? process.env.OLLAMA_BASE_PATH;
|
let urlPath = basePath ?? process.env.OLLAMA_BASE_PATH;
|
||||||
@ -304,7 +304,9 @@ async function ollamaAIModels(basePath = null) {
|
|||||||
return { models: [], error: "Not a valid URL." };
|
return { models: [], error: "Not a valid URL." };
|
||||||
}
|
}
|
||||||
|
|
||||||
const models = await fetch(`${url}/api/tags`)
|
const authToken = _authToken || process.env.OLLAMA_AUTH_TOKEN || null;
|
||||||
|
const headers = authToken ? { Authorization: `Bearer ${authToken}` } : {};
|
||||||
|
const models = await fetch(`${url}/api/tags`, { headers: headers })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok)
|
if (!res.ok)
|
||||||
throw new Error(`Could not reach Ollama server! ${res.status}`);
|
throw new Error(`Could not reach Ollama server! ${res.status}`);
|
||||||
@ -321,6 +323,9 @@ async function ollamaAIModels(basePath = null) {
|
|||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Api Key was successful so lets save it for future uses
|
||||||
|
if (models.length > 0 && !!authToken)
|
||||||
|
process.env.OLLAMA_AUTH_TOKEN = authToken;
|
||||||
return { models, error: null };
|
return { models, error: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -120,6 +120,10 @@ const KEY_MAPPING = {
|
|||||||
envKey: "OLLAMA_KEEP_ALIVE_TIMEOUT",
|
envKey: "OLLAMA_KEEP_ALIVE_TIMEOUT",
|
||||||
checks: [isInteger],
|
checks: [isInteger],
|
||||||
},
|
},
|
||||||
|
OllamaLLMAuthToken: {
|
||||||
|
envKey: "OLLAMA_AUTH_TOKEN",
|
||||||
|
checks: [],
|
||||||
|
},
|
||||||
|
|
||||||
// Mistral AI API Settings
|
// Mistral AI API Settings
|
||||||
MistralApiKey: {
|
MistralApiKey: {
|
||||||
|
|||||||
@ -5198,10 +5198,10 @@ object.values@^1.1.6, object.values@^1.1.7:
|
|||||||
define-properties "^1.2.1"
|
define-properties "^1.2.1"
|
||||||
es-object-atoms "^1.0.0"
|
es-object-atoms "^1.0.0"
|
||||||
|
|
||||||
ollama@^0.5.0:
|
ollama@^0.5.10:
|
||||||
version "0.5.0"
|
version "0.5.12"
|
||||||
resolved "https://registry.yarnpkg.com/ollama/-/ollama-0.5.0.tgz#cb9bc709d4d3278c9f484f751b0d9b98b06f4859"
|
resolved "https://registry.yarnpkg.com/ollama/-/ollama-0.5.12.tgz#d8aadfaff076b2852cf826d928a03d9a40f308b9"
|
||||||
integrity sha512-CRtRzsho210EGdK52GrUMohA2pU+7NbgEaBG3DcYeRmvQthDO7E2LHOkLlUUeaYUlNmEd8icbjC02ug9meSYnw==
|
integrity sha512-flVH1fn1c9NF7VV3bW9kSu0E+bYc40b4DxL/gS2Debhao35osJFRDiPOj9sIWTMvcyj78Paw1OuhfIe7uhDWfQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-fetch "^3.6.20"
|
whatwg-fetch "^3.6.20"
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user