mirror of
https://github.com/getcompanion-ai/alpha-hub.git
synced 2026-04-15 05:02:06 +00:00
Harden alphaXiv transport retries and logging
This commit is contained in:
parent
270eaa1dc5
commit
f6469556f0
1 changed files with 83 additions and 29 deletions
|
|
@ -6,6 +6,43 @@ const ALPHAXIV_MCP_URL = 'https://api.alphaxiv.org/mcp/v1';
|
|||
|
||||
let _client = null;
|
||||
let _connected = false;
|
||||
let _lastTransportLog = { message: '', time: 0 };
|
||||
|
||||
function getErrorMessage(err) {
|
||||
if (!err) return 'Unknown error';
|
||||
if (typeof err === 'string') return err;
|
||||
if (err instanceof Error) return err.message || String(err);
|
||||
return String(err);
|
||||
}
|
||||
|
||||
function isTransientTransportError(err) {
|
||||
const message = getErrorMessage(err);
|
||||
return (
|
||||
message.includes('SSE stream disconnected') ||
|
||||
message.includes('Failed to open SSE stream') ||
|
||||
message.includes('Failed to reconnect SSE stream') ||
|
||||
message.includes('Maximum reconnection attempts') ||
|
||||
message.includes('Bad Gateway') ||
|
||||
message.includes('TypeError: terminated') ||
|
||||
message.includes('terminated')
|
||||
);
|
||||
}
|
||||
|
||||
function logTransportError(err) {
|
||||
const message = getErrorMessage(err);
|
||||
|
||||
if (isTransientTransportError(message)) {
|
||||
const now = Date.now();
|
||||
if (_lastTransportLog.message === message && now - _lastTransportLog.time < 10000) {
|
||||
return;
|
||||
}
|
||||
_lastTransportLog = { message, time: now };
|
||||
process.stderr.write(`[alpha] alphaXiv MCP transient transport issue: ${message}\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
process.stderr.write(`[alpha] alphaXiv MCP error: ${message}\n`);
|
||||
}
|
||||
|
||||
async function getClient() {
|
||||
if (_client && _connected) return _client;
|
||||
|
|
@ -18,7 +55,10 @@ async function getClient() {
|
|||
_client = new Client({ name: 'alpha', version: '0.1.0' });
|
||||
|
||||
_client.onerror = (err) => {
|
||||
process.stderr.write(`[alpha] alphaXiv MCP error: ${err.message || err}\n`);
|
||||
if (isTransientTransportError(err)) {
|
||||
_connected = false;
|
||||
}
|
||||
logTransportError(err);
|
||||
};
|
||||
|
||||
const transport = new StreamableHTTPClientTransport(new URL(ALPHAXIV_MCP_URL), {
|
||||
|
|
@ -36,39 +76,53 @@ async function getClient() {
|
|||
}
|
||||
|
||||
async function callTool(name, args) {
|
||||
let client;
|
||||
try {
|
||||
client = await getClient();
|
||||
} catch (err) {
|
||||
if (err.message?.includes('401') || err.message?.includes('Unauthorized')) {
|
||||
const newToken = await refreshAccessToken();
|
||||
if (newToken) {
|
||||
_client = null;
|
||||
_connected = false;
|
||||
client = await getClient();
|
||||
let lastError = null;
|
||||
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
let client;
|
||||
try {
|
||||
client = await getClient();
|
||||
} catch (err) {
|
||||
if (err.message?.includes('401') || err.message?.includes('Unauthorized')) {
|
||||
const newToken = await refreshAccessToken();
|
||||
if (newToken) {
|
||||
_client = null;
|
||||
_connected = false;
|
||||
client = await getClient();
|
||||
} else {
|
||||
throw new Error('Session expired. Run `alpha login` to re-authenticate.');
|
||||
}
|
||||
} else {
|
||||
throw new Error('Session expired. Run `alpha login` to re-authenticate.');
|
||||
throw err;
|
||||
}
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await client.callTool({ name, arguments: args });
|
||||
|
||||
if (result.isError) {
|
||||
const text = result.content?.[0]?.text || 'Unknown error';
|
||||
throw new Error(text);
|
||||
}
|
||||
|
||||
const text = result.content?.[0]?.text;
|
||||
if (!text) return result.content;
|
||||
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
} catch (err) {
|
||||
lastError = err;
|
||||
if (!isTransientTransportError(err) || attempt === 2) {
|
||||
throw err;
|
||||
}
|
||||
await disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
const result = await client.callTool({ name, arguments: args });
|
||||
|
||||
if (result.isError) {
|
||||
const text = result.content?.[0]?.text || 'Unknown error';
|
||||
throw new Error(text);
|
||||
}
|
||||
|
||||
const text = result.content?.[0]?.text;
|
||||
if (!text) return result.content;
|
||||
|
||||
try {
|
||||
return JSON.parse(text);
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
throw lastError ?? new Error('alphaXiv MCP call failed');
|
||||
}
|
||||
|
||||
export async function searchByEmbedding(query) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue