Replace url.origin with trimTrailingSlash (#4118) * Replace url.origin with trimV1 * Replace url.origin with trimTrailingSlash

358bbf86222a847a102f671d68eee37dd2a3e363

InterestingDarkness <computeridiot999@gmail.com>

Signed
4 files changed, +23 -11Ignore whitespace
src/endpoints/backends/chat-completions.js+4 -3
@@ -16,6 +16,7 @@ import {
16 mergeObjectWithYaml,16 mergeObjectWithYaml,
17 excludeKeysByYaml,17 excludeKeysByYaml,
18 color,18 color,
19 trimTrailingSlash,
19} from '../../util.js';20} from '../../util.js';
20import {21import {
21 convertClaudeMessages,22 convertClaudeMessages,
@@ -1094,11 +1095,11 @@ router.post('/status', async function (request, statusResponse) {
1094 headers = {};1095 headers = {};
1095 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.MAKERSUITE) {1096 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.MAKERSUITE) {
1096 apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);1097 apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);
1097 apiUrl = new URL(request.body.reverse_proxy || API_MAKERSUITE);1098 apiUrl = trimTrailingSlash(request.body.reverse_proxy || API_MAKERSUITE);
1098 const apiVersion = getConfigValue('gemini.apiVersion', 'v1beta');1099 const apiVersion = getConfigValue('gemini.apiVersion', 'v1beta');
1099 const modelsUrl = !apiKey && request.body.reverse_proxy1100 const modelsUrl = !apiKey && request.body.reverse_proxy
1100 ? `${apiUrl.origin}/${apiVersion}/models`1101 ? `${apiUrl}/${apiVersion}/models`
1101 : `${apiUrl.origin}/${apiVersion}/models?key=${apiKey}`;1102 : `${apiUrl}/${apiVersion}/models?key=${apiKey}`;
11021103
1103 if (!apiKey && !request.body.reverse_proxy) {1104 if (!apiKey && !request.body.reverse_proxy) {
1104 console.warn('Google AI Studio API key is missing.');1105 console.warn('Google AI Studio API key is missing.');
src/endpoints/google.js+7 -6
@@ -6,6 +6,7 @@ import crypto from 'node:crypto';
66
7import { readSecret, SECRET_KEYS } from './secrets.js';7import { readSecret, SECRET_KEYS } from './secrets.js';
8import { GEMINI_SAFETY } from '../constants.js';8import { GEMINI_SAFETY } from '../constants.js';
9import { trimTrailingSlash } from '../util.js';
910
10const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';11const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';
11const API_VERTEX_AI = 'https://us-central1-aiplatform.googleapis.com';12const API_VERTEX_AI = 'https://us-central1-aiplatform.googleapis.com';
@@ -148,8 +149,8 @@ router.post('/caption-image', async (request, response) => {
148 if (authType === 'express') {149 if (authType === 'express') {
149 // Express mode: use API key parameter150 // Express mode: use API key parameter
150 const keyParam = authHeader.replace('Bearer ', '');151 const keyParam = authHeader.replace('Bearer ', '');
151 const apiUrl = new URL(request.body.reverse_proxy || API_VERTEX_AI);152 const apiUrl = trimTrailingSlash(request.body.reverse_proxy || API_VERTEX_AI);
152 url = `${apiUrl.origin}/v1/publishers/google/models/${model}:generateContent?key=${keyParam}`;153 url = `${apiUrl}/v1/publishers/google/models/${model}:generateContent?key=${keyParam}`;
153 } else if (authType === 'full') {154 } else if (authType === 'full') {
154 // Full mode: use project-specific URL with Authorization header155 // Full mode: use project-specific URL with Authorization header
155 // Get project ID from Service Account JSON156 // Get project ID from Service Account JSON
@@ -177,15 +178,15 @@ router.post('/caption-image', async (request, response) => {
177 headers['Authorization'] = authHeader;178 headers['Authorization'] = authHeader;
178 } else {179 } else {
179 // Proxy mode: use Authorization header180 // Proxy mode: use Authorization header
180 const apiUrl = new URL(request.body.reverse_proxy || API_VERTEX_AI);181 const apiUrl = trimTrailingSlash(request.body.reverse_proxy || API_VERTEX_AI);
181 url = `${apiUrl.origin}/v1/publishers/google/models/${model}:generateContent`;182 url = `${apiUrl}/v1/publishers/google/models/${model}:generateContent`;
182 headers['Authorization'] = authHeader;183 headers['Authorization'] = authHeader;
183 }184 }
184 } else {185 } else {
185 // Google AI Studio186 // Google AI Studio
186 const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);187 const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);
187 const apiUrl = new URL(request.body.reverse_proxy || API_MAKERSUITE);188 const apiUrl = trimTrailingSlash(request.body.reverse_proxy || API_MAKERSUITE);
188 url = `${apiUrl.origin}/v1beta/models/${model}:generateContent?key=${apiKey}`;189 url = `${apiUrl}/v1beta/models/${model}:generateContent?key=${apiKey}`;
189 }190 }
190 const body = {191 const body = {
191 contents: [{192 contents: [{
src/util.js+9 -0
@@ -659,6 +659,15 @@ export function trimV1(str) {
659}659}
660660
661/**661/**
662 * Removes trailing slash from a string.
663 * @param {string} str Input string
664 * @returns {string} String with trailing slash removed
665 */
666export function trimTrailingSlash(str) {
667 return String(str ?? '').replace(/\/$/, '');
668}
669
670/**
662 * Simple TTL memory cache.671 * Simple TTL memory cache.
663 */672 */
664export class Cache {673export class Cache {
src/vectors/makersuite-vectors.js+3 -2
@@ -1,5 +1,6 @@
1import fetch from 'node-fetch';1import fetch from 'node-fetch';
2import { SECRET_KEYS, readSecret } from '../endpoints/secrets.js';2import { SECRET_KEYS, readSecret } from '../endpoints/secrets.js';
3import { trimTrailingSlash } from '../util.js';
3const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';4const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';
45
5/**6/**
@@ -27,9 +28,9 @@ export async function getMakerSuiteVector(text, directories) {
27 throw new Error('No Google AI Studio key found');28 throw new Error('No Google AI Studio key found');
28 }29 }
2930
30 const apiUrl = new URL(API_MAKERSUITE);31 const apiUrl = trimTrailingSlash(API_MAKERSUITE);
31 const model = 'text-embedding-004';32 const model = 'text-embedding-004';
32 const url = `${apiUrl.origin}/v1beta/models/${model}:embedContent?key=${key}`;33 const url = `${apiUrl}/v1beta/models/${model}:embedContent?key=${key}`;
33 const body = {34 const body = {
34 content: {35 content: {
35 parts: [36 parts: [