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 {
1616 mergeObjectWithYaml,
1717 excludeKeysByYaml,
1818 color,
19+ trimTrailingSlash,
1920} from '../../util.js';
2021import {
2122 convertClaudeMessages,
@@ -1094,11 +1095,11 @@ router.post('/status', async function (request, statusResponse) {
10941095 headers = {};
10951096 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.MAKERSUITE) {
10961097 apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);
10971098 apiUrl = new URLtrimTrailingSlash(request.body.reverse_proxy || API_MAKERSUITE);
10981099 const apiVersion = getConfigValue('gemini.apiVersion', 'v1beta');
10991100 const modelsUrl = !apiKey && request.body.reverse_proxy
11001101 ? `${apiUrl.origin}/${apiVersion}/models`
11011102 : `${apiUrl.origin}/${apiVersion}/models?key=${apiKey}`;
11021103
11031104 if (!apiKey && !request.body.reverse_proxy) {
11041105 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
77import { readSecret, SECRET_KEYS } from './secrets.js';
88import { GEMINI_SAFETY } from '../constants.js';
9+import { trimTrailingSlash } from '../util.js';
910
1011const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';
1112const API_VERTEX_AI = 'https://us-central1-aiplatform.googleapis.com';
@@ -148,8 +149,8 @@ router.post('/caption-image', async (request, response) => {
148149 if (authType === 'express') {
149150 // Express mode: use API key parameter
150151 const keyParam = authHeader.replace('Bearer ', '');
151152 const apiUrl = new URLtrimTrailingSlash(request.body.reverse_proxy || API_VERTEX_AI);
152153 url = `${apiUrl.origin}/v1/publishers/google/models/${model}:generateContent?key=${keyParam}`;
153154 } else if (authType === 'full') {
154155 // Full mode: use project-specific URL with Authorization header
155156 // Get project ID from Service Account JSON
@@ -177,15 +178,15 @@ router.post('/caption-image', async (request, response) => {
177178 headers['Authorization'] = authHeader;
178179 } else {
179180 // Proxy mode: use Authorization header
180181 const apiUrl = new URLtrimTrailingSlash(request.body.reverse_proxy || API_VERTEX_AI);
181182 url = `${apiUrl.origin}/v1/publishers/google/models/${model}:generateContent`;
182183 headers['Authorization'] = authHeader;
183184 }
184185 } else {
185186 // Google AI Studio
186187 const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE);
187188 const apiUrl = new URLtrimTrailingSlash(request.body.reverse_proxy || API_MAKERSUITE);
188189 url = `${apiUrl.origin}/v1beta/models/${model}:generateContent?key=${apiKey}`;
189190 }
190191 const body = {
191192 contents: [{
src/util.js+9 -0
@@ -659,6 +659,15 @@ export function trimV1(str) {
659659}
660660
661661/**
662+ * Removes trailing slash from a string.
663+ * @param {string} str Input string
664+ * @returns {string} String with trailing slash removed
665+ */
666+export function trimTrailingSlash(str) {
667+ return String(str ?? '').replace(/\/$/, '');
668+}
669+
670+/**
662671 * Simple TTL memory cache.
663672 */
664673export class Cache {
src/vectors/makersuite-vectors.js+3 -2
@@ -1,5 +1,6 @@
11import fetch from 'node-fetch';
22import { SECRET_KEYS, readSecret } from '../endpoints/secrets.js';
3+import { trimTrailingSlash } from '../util.js';
34const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';
45
56/**
@@ -27,9 +28,9 @@ export async function getMakerSuiteVector(text, directories) {
2728 throw new Error('No Google AI Studio key found');
2829 }
2930
3031 const apiUrl = new URLtrimTrailingSlash(API_MAKERSUITE);
3132 const model = 'text-embedding-004';
3233 const url = `${apiUrl.origin}/v1beta/models/${model}:embedContent?key=${key}`;
3334 const body = {
3435 content: {
3536 parts: [