piclets / src /lib /services /textGenerationClient.ts
Fraser's picture
no test connection
a588516
raw
history blame
4.32 kB
/**
* Text Generation Client Manager
* Provides unified interface for text generation with automatic fallback
* Primary: Qwen3 (Qwen/Qwen3-Demo), Fallback: Zephyr-7B (Fraser/zephyr-7b)
*/
import { qwen3Client } from './qwen3Client';
interface TextGenerationClient {
predict(endpoint: string, params: any[]): Promise<{data: any[]}>;
testConnection?(): Promise<boolean>;
}
class TextGenerationManager {
private primaryClient: TextGenerationClient;
private fallbackClient: TextGenerationClient | null = null;
private useQwen3: boolean = true;
private connectionTested: boolean = false;
constructor() {
this.primaryClient = qwen3Client;
}
/**
* Set the fallback client (Zephyr-7B)
*/
setFallbackClient(client: TextGenerationClient) {
this.fallbackClient = client;
}
/**
* Initialize without testing - assume Qwen3 is available and test on first real use
*/
async initialize(): Promise<void> {
if (this.connectionTested) return;
console.log('πŸ”§ Initializing text generation manager - using Qwen3 but will fallback to Zephyr-7B on failure');
// Default to using Qwen3, test will happen on first predict() call
this.useQwen3 = true;
this.connectionTested = true;
console.log('βœ… Text generation manager initialized - ready to use Qwen3 (with fallback to Zephyr-7B)');
}
/**
* Get the active client for text generation
*/
private getActiveClient(): TextGenerationClient {
if (this.useQwen3) {
return this.primaryClient;
} else if (this.fallbackClient) {
return this.fallbackClient;
} else {
console.warn('No fallback client available, using Qwen3 client');
return this.primaryClient;
}
}
/**
* Predict method with automatic fallback - tests on first failure
*/
async predict(endpoint: string, params: any[]): Promise<{data: any[]}> {
// Ensure initialization has been attempted
if (!this.connectionTested) {
await this.initialize();
}
const activeClient = this.getActiveClient();
const clientName = this.useQwen3 ? 'Qwen3' : 'Zephyr-7B';
console.log(`πŸ€– Using ${clientName} for text generation`);
try {
const result = await activeClient.predict(endpoint, params);
return result;
} catch (error) {
console.error(`${clientName} prediction failed:`, error);
// If primary client fails and we have a fallback, try it
if (this.useQwen3 && this.fallbackClient) {
console.log('πŸ”„ Qwen3 failed, switching to fallback Zephyr-7B...');
try {
const fallbackResult = await this.fallbackClient.predict(endpoint, params);
// Mark for future calls to use fallback
this.useQwen3 = false;
console.log('βœ… Fallback to Zephyr-7B successful - will use Zephyr-7B for future requests');
return fallbackResult;
} catch (fallbackError) {
console.error('Fallback client also failed:', fallbackError);
throw new Error(`Both primary (${clientName}) and fallback clients failed`);
}
}
throw error;
}
}
/**
* Force switch to Qwen3
*/
useQwen3Client() {
this.useQwen3 = true;
console.log('πŸ”„ Switched to Qwen3 client');
}
/**
* Force switch to fallback (Zephyr-7B)
*/
useFallbackClient() {
if (this.fallbackClient) {
this.useQwen3 = false;
console.log('πŸ”„ Switched to fallback (Zephyr-7B) client');
} else {
console.warn('No fallback client available');
}
}
/**
* Get current client status
*/
getStatus() {
return {
usingQwen3: this.useQwen3,
hasFallback: this.fallbackClient !== null,
connectionTested: this.connectionTested,
activeClient: this.useQwen3 ? 'Qwen3' : 'Zephyr-7B'
};
}
/**
* Reset connection testing to allow re-initialization
*/
resetConnectionTest() {
this.connectionTested = false;
console.log('πŸ”„ Connection test reset - will re-test on next prediction');
}
/**
* Force re-test connection and re-initialize
*/
async retestConnection(): Promise<void> {
this.connectionTested = false;
await this.initialize();
}
}
// Export singleton instance
export const textGenerationManager = new TextGenerationManager();