Open labolado opened 2 months ago
I have met the same issue. Is there any solution on it?
I have met the same issue. Is there any solution on it?
There is no solution yet.
Use Cloudflare Workers to proxy your API and alias the model name.
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
const BASE_URL = 'https://my_api_url'
const MODEL_ALIASES = {
'mymodel': 'claude-3-5-sonnet-20240620'
}
async function handleRequest(request) {
const url = new URL(request.url)
const path = url.pathname
const queryParams = url.search
console.log(`Received request: ${request.method} ${path}`)
if (request.method === 'GET' && path === '/') {
return new Response("Claude API Proxy is running!", { status: 200 })
}
if ((request.method === 'POST' && path === '/v1/chat/completions') ||
(request.method === 'GET' && path === '/v1/models')) {
return await proxyRequest(request, path, queryParams)
}
console.log(`Unhandled route: ${path}`)
return new Response(JSON.stringify({ error: 'Not Found', path: path }), {
status: 404,
headers: { 'Content-Type': 'application/json' }
})
}
async function proxyRequest(request, path, queryParams) {
const authHeader = request.headers.get('Authorization')
if (!authHeader || !authHeader.startsWith('Bearer ')) {
console.log('Missing or invalid Authorization header')
return new Response(JSON.stringify({ error: 'Valid Authorization header is required' }), {
status: 401,
headers: { 'Content-Type': 'application/json' }
})
}
const apiKey = authHeader.split(' ')[1]
const url = BASE_URL + path + queryParams
const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
let body = request.body
if (path === '/v1/chat/completions' && request.method === 'POST') {
const requestData = await request.json()
console.log(`Request data: ${JSON.stringify(requestData)}`)
if (requestData.model && MODEL_ALIASES[requestData.model]) {
requestData.model = MODEL_ALIASES[requestData.model]
}
body = JSON.stringify(requestData)
}
try {
console.log(`Sending request to: ${url}`)
const response = await fetch(url, {
method: request.method,
headers: headers,
body: body
})
const responseData = await response.text()
console.log(`Received response: ${responseData}`)
return new Response(responseData, {
status: response.status,
headers: {
'Content-Type': 'application/json'
}
})
} catch (error) {
console.error(`Error: ${error.message}`)
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: {
'Content-Type': 'application/json'
}
})
}
}
Use Cloudflare Workers to proxy your API and alias the model name.
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) const BASE_URL = 'https://my_api_url' const MODEL_ALIASES = { 'mymodel': 'claude-3-5-sonnet-20240620' } async function handleRequest(request) { const url = new URL(request.url) const path = url.pathname const queryParams = url.search console.log(`Received request: ${request.method} ${path}`) if (request.method === 'GET' && path === '/') { return new Response("Claude API Proxy is running!", { status: 200 }) } if ((request.method === 'POST' && path === '/v1/chat/completions') || (request.method === 'GET' && path === '/v1/models')) { return await proxyRequest(request, path, queryParams) } console.log(`Unhandled route: ${path}`) return new Response(JSON.stringify({ error: 'Not Found', path: path }), { status: 404, headers: { 'Content-Type': 'application/json' } }) } async function proxyRequest(request, path, queryParams) { const authHeader = request.headers.get('Authorization') if (!authHeader || !authHeader.startsWith('Bearer ')) { console.log('Missing or invalid Authorization header') return new Response(JSON.stringify({ error: 'Valid Authorization header is required' }), { status: 401, headers: { 'Content-Type': 'application/json' } }) } const apiKey = authHeader.split(' ')[1] const url = BASE_URL + path + queryParams const headers = { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } let body = request.body if (path === '/v1/chat/completions' && request.method === 'POST') { const requestData = await request.json() console.log(`Request data: ${JSON.stringify(requestData)}`) if (requestData.model && MODEL_ALIASES[requestData.model]) { requestData.model = MODEL_ALIASES[requestData.model] } body = JSON.stringify(requestData) } try { console.log(`Sending request to: ${url}`) const response = await fetch(url, { method: request.method, headers: headers, body: body }) const responseData = await response.text() console.log(`Received response: ${responseData}`) return new Response(responseData, { status: response.status, headers: { 'Content-Type': 'application/json' } }) } catch (error) { console.error(`Error: ${error.message}`) return new Response(JSON.stringify({ error: error.message }), { status: 500, headers: { 'Content-Type': 'application/json' } }) } }
Hi @labolado, may I ask which custom API do you use—-CloseAI, OpenRoute, or others? I use CloseAI, but I'm encountering issues with Claude with your script. Could you provide more information? Thanks.
When I use a custom OpenAI base URL and OpenAI key, an error occurs if my model name uses the Claude-related model name (claude-3-5-sonnet-20240620): You're using your own API key, and we got the following error from Anthropic: {"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}
PS: I've disabled the Anthropic Api Key.
版本: 0.39.5 提交: 1.91.1 日期: 274e2e5d572bd0b99449183635a0f94c7b9f54d0 Electron: 2024-08-14T15:49:16.270Z ElectronBuildId: 29.4.0 Chromium: undefined Node.js: 122.0.6261.156 V8: 20.9.0 OS: 12.2.281.27-electron.0