File size: 4,136 Bytes
24561f7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
/**
* 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;
}
/**
* Test connection and determine which client to use
*/
async initialize(): Promise<void> {
if (this.connectionTested) return;
console.log('Testing Qwen3 connection...');
try {
if (this.primaryClient.testConnection) {
const qwen3Available = await this.primaryClient.testConnection();
if (qwen3Available) {
console.log('β
Qwen3 client is available and will be used for text generation');
this.useQwen3 = true;
} else {
console.log('β οΈ Qwen3 client is not available, falling back to Zephyr-7B');
this.useQwen3 = false;
}
}
} catch (error) {
console.error('Failed to test Qwen3 connection:', error);
console.log('β οΈ Falling back to Zephyr-7B due to connection error');
this.useQwen3 = false;
}
this.connectionTested = true;
}
/**
* 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
*/
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, trying fallback to Zephyr-7B...');
try {
const fallbackResult = await this.fallbackClient.predict(endpoint, params);
// Mark for future calls to use fallback
this.useQwen3 = false;
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'
};
}
}
// Export singleton instance
export const textGenerationManager = new TextGenerationManager(); |