implement custom API endpoint support: centralized config function intercepts all chat API calls

This commit is contained in:
Russell Ballestrini 2025-07-10 23:38:05 -04:00
parent 8560ea43ce
commit 96082cf750
2 changed files with 82 additions and 16 deletions

View file

@ -1,7 +1,7 @@
// Chat functionality and message handling
import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
import hljs from "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/es/highlight.min.js";
import { API_KEY } from "./config.js";
import { API_KEY, getAPIConfig } from "./config.js";
import { getSelectedModel, getSelectedModelEndpoint } from "./models.js";
import { initializeChatHistory, saveConversationHistory } from "./storage.js";
import { generateTitleForTTS, speakText } from "./tts.js";
@ -51,18 +51,31 @@ export let chatHistory = initializeChatHistory();
export async function* sendMessage(message) {
chatHistory.push({ role: "user", content: message });
// Dynamically determine the API URL based on the selected model.
// (Assuming that the chat completions endpoint is at "/chat/completions")
const apiUrl = `${getSelectedModelEndpoint()}/chat/completions`;
// Get API configuration (custom or default)
const apiConfig = getAPIConfig();
let apiUrl, headers, model;
if (apiConfig.isCustom) {
// Use custom API configuration
apiUrl = `${apiConfig.endpoint}/chat/completions`;
headers = apiConfig.headers;
model = apiConfig.model;
} else {
// Use default Hermes configuration
apiUrl = `${getSelectedModelEndpoint()}/chat/completions`;
headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
};
model = getSelectedModel();
}
const response = await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
},
headers: headers,
body: JSON.stringify({
model: getSelectedModel(),
model: model,
messages: chatHistory,
temperature: 0.5,
max_tokens: 8192,
@ -198,17 +211,31 @@ export function getChatHistory() {
// Generator function to send a message with custom history (doesn't modify global chatHistory)
export async function* sendMessageWithCustomHistory(customHistory) {
// Dynamically determine the API URL based on the selected model.
const apiUrl = `${getSelectedModelEndpoint()}/chat/completions`;
// Get API configuration (custom or default)
const apiConfig = getAPIConfig();
let apiUrl, headers, model;
if (apiConfig.isCustom) {
// Use custom API configuration
apiUrl = `${apiConfig.endpoint}/chat/completions`;
headers = apiConfig.headers;
model = apiConfig.model;
} else {
// Use default Hermes configuration
apiUrl = `${getSelectedModelEndpoint()}/chat/completions`;
headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
};
model = getSelectedModel();
}
const response = await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${API_KEY}`,
},
headers: headers,
body: JSON.stringify({
model: getSelectedModel(),
model: model,
messages: customHistory,
stream: true,
}),

View file

@ -69,6 +69,45 @@ export const VLLM_ENDPOINTS = [
{ id: "hermes2.ai.unturf.com", url: "https://hermes2.ai.unturf.com/v1" },
];
// Function to get API configuration (custom or default)
export function getAPIConfig() {
try {
const useCustomAPI = localStorage.getItem("useCustomAPI") === "true";
if (useCustomAPI) {
const customBaseURL = localStorage.getItem("customBaseURL");
const customAPIKey = localStorage.getItem("customAPIKey");
const customModelName = localStorage.getItem("customModelName");
if (customBaseURL && customAPIKey && customModelName) {
return {
isCustom: true,
endpoint: customBaseURL,
apiKey: customAPIKey,
model: customModelName,
headers: {
"Authorization": `Bearer ${customAPIKey}`,
"Content-Type": "application/json"
}
};
}
}
} catch (error) {
console.warn("Failed to read custom API settings:", error);
}
// Return default configuration
return {
isCustom: false,
endpoints: VLLM_ENDPOINTS,
model: MODEL,
apiKey: API_KEY,
headers: {
"Content-Type": "application/json"
}
};
}
// Global state
export let lastTTSInput = "";
export let lastTTSResult = null;