removing restcting of available models, fixing max tokens issues in test
This commit is contained in:
@@ -13,13 +13,11 @@ import crypto from 'crypto';
|
||||
import {
|
||||
ANTIGRAVITY_ENDPOINT_FALLBACKS,
|
||||
ANTIGRAVITY_HEADERS,
|
||||
AVAILABLE_MODELS,
|
||||
MAX_RETRIES,
|
||||
MAX_WAIT_BEFORE_ERROR_MS,
|
||||
MIN_SIGNATURE_LENGTH
|
||||
} from './constants.js';
|
||||
import {
|
||||
mapModelName,
|
||||
convertAnthropicToGoogle,
|
||||
convertGoogleToAnthropic
|
||||
} from './format-converter.js';
|
||||
@@ -219,7 +217,7 @@ function parseResetTime(responseOrError, errorText = '') {
|
||||
* Build the wrapped request body for Cloud Code API
|
||||
*/
|
||||
function buildCloudCodeRequest(anthropicRequest, projectId) {
|
||||
const model = mapModelName(anthropicRequest.model);
|
||||
const model = anthropicRequest.model;
|
||||
const googleRequest = convertAnthropicToGoogle(anthropicRequest);
|
||||
|
||||
// Use stable session ID derived from first user message for cache continuity
|
||||
@@ -247,7 +245,7 @@ function buildHeaders(token, model, accept = 'application/json') {
|
||||
};
|
||||
|
||||
// Add interleaved thinking header for Claude thinking models
|
||||
const isThinkingModel = model.toLowerCase().includes('thinking');
|
||||
const isThinkingModel = model.toLowerCase().includes('claude') && model.toLowerCase().includes('thinking');
|
||||
if (isThinkingModel) {
|
||||
headers['anthropic-beta'] = 'interleaved-thinking-2025-05-14';
|
||||
}
|
||||
@@ -273,8 +271,8 @@ function buildHeaders(token, model, accept = 'application/json') {
|
||||
* @throws {Error} If max retries exceeded or no accounts available
|
||||
*/
|
||||
export async function sendMessage(anthropicRequest, accountManager) {
|
||||
const model = mapModelName(anthropicRequest.model);
|
||||
const isThinkingModel = model.toLowerCase().includes('thinking');
|
||||
const model = anthropicRequest.model;
|
||||
const isThinkingModel = model.toLowerCase().includes('claude') && model.toLowerCase().includes('thinking');
|
||||
|
||||
// Retry loop with account failover
|
||||
// Ensure we try at least as many times as there are accounts to cycle through everyone
|
||||
@@ -537,7 +535,7 @@ async function parseThinkingSSEResponse(response, originalModel) {
|
||||
* @throws {Error} If max retries exceeded or no accounts available
|
||||
*/
|
||||
export async function* sendMessageStream(anthropicRequest, accountManager) {
|
||||
const model = mapModelName(anthropicRequest.model);
|
||||
const model = anthropicRequest.model;
|
||||
|
||||
// Retry loop with account failover
|
||||
// Ensure we try at least as many times as there are accounts to cycle through everyone
|
||||
@@ -931,19 +929,28 @@ async function* streamSSEResponse(response, originalModel) {
|
||||
|
||||
/**
|
||||
* List available models in Anthropic API format
|
||||
* Fetches models dynamically from the Cloud Code API
|
||||
*
|
||||
* @returns {{object: string, data: Array<{id: string, object: string, created: number, owned_by: string, description: string}>}} List of available models
|
||||
* @param {string} token - OAuth access token
|
||||
* @returns {Promise<{object: string, data: Array<{id: string, object: string, created: number, owned_by: string, description: string}>}>} List of available models
|
||||
*/
|
||||
export function listModels() {
|
||||
export async function listModels(token) {
|
||||
const data = await fetchAvailableModels(token);
|
||||
if (!data || !data.models) {
|
||||
return { object: 'list', data: [] };
|
||||
}
|
||||
|
||||
const modelList = Object.entries(data.models).map(([modelId, modelData]) => ({
|
||||
id: modelId,
|
||||
object: 'model',
|
||||
created: Math.floor(Date.now() / 1000),
|
||||
owned_by: 'anthropic',
|
||||
description: modelData.displayName || modelId
|
||||
}));
|
||||
|
||||
return {
|
||||
object: 'list',
|
||||
data: AVAILABLE_MODELS.map(m => ({
|
||||
id: m.id,
|
||||
object: 'model',
|
||||
created: Math.floor(Date.now() / 1000),
|
||||
owned_by: 'anthropic',
|
||||
description: m.description
|
||||
}))
|
||||
data: modelList
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -56,44 +56,6 @@ export const ANTIGRAVITY_HEADERS = {
|
||||
})
|
||||
};
|
||||
|
||||
// Model name mappings: Anthropic format → Antigravity format
|
||||
export const MODEL_MAPPINGS = {
|
||||
// Claude models
|
||||
'claude-3-opus-20240229': 'claude-opus-4-5-thinking',
|
||||
'claude-3-5-opus-20240229': 'claude-opus-4-5-thinking',
|
||||
'claude-3-5-sonnet-20241022': 'claude-sonnet-4-5',
|
||||
'claude-3-5-sonnet-20240620': 'claude-sonnet-4-5',
|
||||
'claude-3-sonnet-20240229': 'claude-sonnet-4-5',
|
||||
'claude-sonnet-4-5': 'claude-sonnet-4-5',
|
||||
'claude-sonnet-4-5-thinking': 'claude-sonnet-4-5-thinking',
|
||||
'claude-opus-4-5-thinking': 'claude-opus-4-5-thinking'
|
||||
};
|
||||
|
||||
// Available models exposed by this proxy
|
||||
export const AVAILABLE_MODELS = [
|
||||
{
|
||||
id: 'claude-sonnet-4-5',
|
||||
name: 'Claude Sonnet 4.5 (Antigravity)',
|
||||
description: 'Claude Sonnet 4.5 via Antigravity Cloud Code',
|
||||
context: 200000,
|
||||
output: 64000
|
||||
},
|
||||
{
|
||||
id: 'claude-sonnet-4-5-thinking',
|
||||
name: 'Claude Sonnet 4.5 Thinking (Antigravity)',
|
||||
description: 'Claude Sonnet 4.5 with extended thinking via Antigravity',
|
||||
context: 200000,
|
||||
output: 64000
|
||||
},
|
||||
{
|
||||
id: 'claude-opus-4-5-thinking',
|
||||
name: 'Claude Opus 4.5 Thinking (Antigravity)',
|
||||
description: 'Claude Opus 4.5 with extended thinking via Antigravity',
|
||||
context: 200000,
|
||||
output: 64000
|
||||
}
|
||||
];
|
||||
|
||||
// Default project ID if none can be discovered
|
||||
export const DEFAULT_PROJECT_ID = 'rising-fact-p41fc';
|
||||
|
||||
@@ -120,7 +82,6 @@ export const MAX_ACCOUNTS = 10; // Maximum number of accounts allowed
|
||||
export const MAX_WAIT_BEFORE_ERROR_MS = 120000; // 2 minutes - throw error if wait exceeds this
|
||||
|
||||
// Thinking model constants
|
||||
export const CLAUDE_THINKING_MAX_OUTPUT_TOKENS = 64000; // Max output tokens for thinking models
|
||||
export const MIN_SIGNATURE_LENGTH = 50; // Minimum valid thinking signature length
|
||||
|
||||
// Google OAuth configuration (from opencode-antigravity-auth)
|
||||
@@ -144,8 +105,6 @@ export const OAUTH_REDIRECT_URI = `http://localhost:${OAUTH_CONFIG.callbackPort}
|
||||
export default {
|
||||
ANTIGRAVITY_ENDPOINT_FALLBACKS,
|
||||
ANTIGRAVITY_HEADERS,
|
||||
MODEL_MAPPINGS,
|
||||
AVAILABLE_MODELS,
|
||||
DEFAULT_PROJECT_ID,
|
||||
TOKEN_REFRESH_INTERVAL_MS,
|
||||
REQUEST_BODY_LIMIT,
|
||||
@@ -157,7 +116,6 @@ export default {
|
||||
MAX_RETRIES,
|
||||
MAX_ACCOUNTS,
|
||||
MAX_WAIT_BEFORE_ERROR_MS,
|
||||
CLAUDE_THINKING_MAX_OUTPUT_TOKENS,
|
||||
MIN_SIGNATURE_LENGTH,
|
||||
OAUTH_CONFIG,
|
||||
OAUTH_REDIRECT_URI
|
||||
|
||||
@@ -9,20 +9,9 @@
|
||||
|
||||
import crypto from 'crypto';
|
||||
import {
|
||||
MODEL_MAPPINGS,
|
||||
CLAUDE_THINKING_MAX_OUTPUT_TOKENS,
|
||||
MIN_SIGNATURE_LENGTH
|
||||
} from './constants.js';
|
||||
|
||||
/**
|
||||
* Map Anthropic model name to Antigravity model name
|
||||
* @param {string} anthropicModel - Anthropic format model name (e.g., 'claude-3-5-sonnet-20241022')
|
||||
* @returns {string} Antigravity format model name (e.g., 'claude-sonnet-4-5')
|
||||
*/
|
||||
export function mapModelName(anthropicModel) {
|
||||
return MODEL_MAPPINGS[anthropicModel] || anthropicModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a part is a thinking block
|
||||
* @param {Object} part - Content part to check
|
||||
@@ -509,13 +498,6 @@ export function convertAnthropicToGoogle(anthropicRequest) {
|
||||
const thinkingBudget = thinking?.budget_tokens;
|
||||
if (thinkingBudget) {
|
||||
thinkingConfig.thinking_budget = thinkingBudget;
|
||||
|
||||
// Ensure maxOutputTokens is large enough when budget is specified
|
||||
if (!googleRequest.generationConfig.maxOutputTokens ||
|
||||
googleRequest.generationConfig.maxOutputTokens <= thinkingBudget) {
|
||||
googleRequest.generationConfig.maxOutputTokens = CLAUDE_THINKING_MAX_OUTPUT_TOKENS;
|
||||
}
|
||||
|
||||
console.log('[FormatConverter] Thinking enabled with budget:', thinkingBudget);
|
||||
} else {
|
||||
console.log('[FormatConverter] Thinking enabled (no budget specified)');
|
||||
@@ -725,7 +707,6 @@ export function convertGoogleToAnthropic(googleResponse, model) {
|
||||
}
|
||||
|
||||
export default {
|
||||
mapModelName,
|
||||
convertAnthropicToGoogle,
|
||||
convertGoogleToAnthropic
|
||||
};
|
||||
|
||||
@@ -193,7 +193,7 @@ app.get('/account-limits', async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
const sortedModels = Array.from(allModelIds).filter(m => m.includes('claude')).sort();
|
||||
const sortedModels = Array.from(allModelIds).sort();
|
||||
|
||||
// Return ASCII table format
|
||||
if (format === 'table') {
|
||||
@@ -352,8 +352,32 @@ app.post('/refresh-token', async (req, res) => {
|
||||
/**
|
||||
* List models endpoint (OpenAI-compatible format)
|
||||
*/
|
||||
app.get('/v1/models', (req, res) => {
|
||||
res.json(listModels());
|
||||
app.get('/v1/models', async (req, res) => {
|
||||
try {
|
||||
await ensureInitialized();
|
||||
const account = accountManager.pickNext();
|
||||
if (!account) {
|
||||
return res.status(503).json({
|
||||
type: 'error',
|
||||
error: {
|
||||
type: 'api_error',
|
||||
message: 'No accounts available'
|
||||
}
|
||||
});
|
||||
}
|
||||
const token = await accountManager.getTokenForAccount(account);
|
||||
const models = await listModels(token);
|
||||
res.json(models);
|
||||
} catch (error) {
|
||||
console.error('[API] Error listing models:', error);
|
||||
res.status(500).json({
|
||||
type: 'error',
|
||||
error: {
|
||||
type: 'api_error',
|
||||
message: error.message
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user