UNPKG

resig.js

Version:

Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.

277 lines 21.5 kB
/** * AI Transformer Interface * Streaming AI integration with confidence tracking and token management */ import { signal } from '../core/signal'; import { createStreamingSignal } from './coalgebra'; // Base AI transformer implementation export class BaseAITransformer { constructor(config) { this.confidenceSignal = signal(0); this.tokensSignal = signal({ input: 0, output: 0, total: 0, }); this.processingSignal = signal(false); this.config = { ...config }; this.rateLimitState = { requestCount: 0, windowStart: Date.now(), maxRequests: 60, // Default: 60 requests per minute windowSize: 60000, }; } transform(input) { const output = createStreamingSignal(null); input.subscribe(async (inputValue) => { if (inputValue === null || inputValue === undefined) return; try { this.processingSignal._set(true); // Check rate limiting await this.checkRateLimit(); // Process the request const response = await this.processRequest(inputValue); // Update signals this.confidenceSignal._set(response.confidence); this.tokensSignal._set(response.tokens); output._set(response.data); } catch (error) { console.error('AI transformer error:', error); this.confidenceSignal._set(0); } finally { this.processingSignal._set(false); } }); return output; } async checkRateLimit() { const now = Date.now(); // Reset window if needed if (now - this.rateLimitState.windowStart >= this.rateLimitState.windowSize) { this.rateLimitState.requestCount = 0; this.rateLimitState.windowStart = now; } // Check if we've exceeded the limit if (this.rateLimitState.requestCount >= this.rateLimitState.maxRequests) { const waitTime = this.rateLimitState.windowSize - (now - this.rateLimitState.windowStart); await new Promise((resolve) => setTimeout(resolve, waitTime)); return this.checkRateLimit(); } this.rateLimitState.requestCount++; } confidence() { return this.confidenceSignal; } tokens() { return this.tokensSignal; } isProcessing() { return this.processingSignal; } getModel() { return this.config.model; } setConfig(config) { this.config = { ...this.config, ...config }; } } // OpenAI GPT transformer export class OpenAITransformer extends BaseAITransformer { async processRequest(input) { const startTime = Date.now(); try { const response = await fetch(`${this.config.baseURL || 'https://api.openai.com/v1'}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.config.apiKey}`, }, body: JSON.stringify({ model: this.config.model === 'gpt-4' ? 'gpt-4' : 'gpt-3.5-turbo', messages: [{ role: 'user', content: input }], max_tokens: this.config.maxTokens, temperature: this.config.temperature, stream: this.config.streaming, }), }); if (!response.ok) { throw new Error(`OpenAI API error: ${response.status}`); } const data = await response.json(); const choice = data.choices[0]; const usage = data.usage; return { data: choice.message.content, confidence: this.calculateConfidence(choice), tokens: { input: usage.prompt_tokens, output: usage.completion_tokens, total: usage.total_tokens, }, processingTime: Date.now() - startTime, model: data.model, timestamp: Date.now(), }; } catch (error) { throw new Error(`OpenAI processing failed: ${error}`); } } calculateConfidence(choice) { // Simple confidence calculation based on finish_reason and logprobs if (choice.finish_reason === 'stop') return 0.9; if (choice.finish_reason === 'length') return 0.7; return 0.5; } } // Mock AI transformer for testing export class MockAITransformer extends BaseAITransformer { async processRequest(input) { const startTime = Date.now(); // Simulate processing delay await new Promise((resolve) => setTimeout(resolve, 100 + Math.random() * 500)); const output = `AI response to: "${input}"`; const inputTokens = Math.ceil(input.length / 4); // Rough token estimation const outputTokens = Math.ceil(output.length / 4); return { data: output, confidence: 0.8 + Math.random() * 0.2, tokens: { input: inputTokens, output: outputTokens, total: inputTokens + outputTokens, }, processingTime: Date.now() - startTime, model: 'mock-ai', timestamp: Date.now(), }; } } // Multi-modal AI transformer for vision + language export class MultiModalTransformer extends BaseAITransformer { async processRequest(input) { const startTime = Date.now(); // Simulate multi-modal processing await new Promise((resolve) => setTimeout(resolve, 200 + Math.random() * 800)); let response = ''; if (input.text) response += `Text analysis: ${input.text}. `; if (input.image) response += `Image analysis: [Image content description]. `; const inputTokens = (input.text?.length || 0) / 4 + (input.image ? 100 : 0); // Images cost more tokens const outputTokens = response.length / 4; return { data: response.trim(), confidence: 0.75 + Math.random() * 0.25, tokens: { input: Math.ceil(inputTokens), output: Math.ceil(outputTokens), total: Math.ceil(inputTokens + outputTokens), }, processingTime: Date.now() - startTime, model: 'multimodal-ai', timestamp: Date.now(), }; } } // Factory functions for creating AI transformers export const createLLMTransformer = (model, config = {}) => { const fullConfig = { model, maxTokens: 4000, temperature: 0.7, streaming: false, timeout: 30000, retryAttempts: 3, rateLimitDelay: 1000, ...config, }; switch (model) { case 'gpt-4': return new OpenAITransformer(fullConfig); case 'custom': return new MockAITransformer(fullConfig); default: return new MockAITransformer(fullConfig); } }; export const createVisionModel = (_model, config = {}) => { const fullConfig = { model: 'custom', maxTokens: 2000, temperature: 0.5, streaming: false, timeout: 45000, retryAttempts: 2, rateLimitDelay: 2000, ...config, }; return new MultiModalTransformer(fullConfig); }; // AI agent composition utilities export const composeAITransformers = (first, second) => { return { transform: (input) => { const intermediate = first.transform(input); return second.transform(intermediate); }, confidence: () => { // Combined confidence is the minimum of both const conf1 = first.confidence().value(); const conf2 = second.confidence().value(); return signal(Math.min(conf1, conf2)); }, tokens: () => { // Combined token usage const tokens1 = first.tokens().value(); const tokens2 = second.tokens().value(); return signal({ input: tokens1.input, output: tokens2.output, total: tokens1.total + tokens2.total, }); }, isProcessing: () => { // Either transformer is processing const proc1 = first.isProcessing().value(); const proc2 = second.isProcessing().value(); return signal(proc1 || proc2); }, getModel: () => 'composed', setConfig: (config) => { first.setConfig(config); second.setConfig(config); }, }; }; // Batch processing for multiple inputs export const createBatchAITransformer = (baseTransformer, batchSize = 10) => { return { transform: (input) => { const batched = input.buffer(batchSize); const batchOutput = baseTransformer.transform(batched); // Flatten batch output back to individual items const output = createStreamingSignal(null); batchOutput.subscribe((batch) => { if (batch && Array.isArray(batch)) { batch.forEach((item) => output._set(item)); } }); return output; }, confidence: baseTransformer.confidence, tokens: baseTransformer.tokens, isProcessing: baseTransformer.isProcessing, getModel: baseTransformer.getModel, setConfig: baseTransformer.setConfig, }; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktdHJhbnNmb3JtZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3RyZWFtaW5nL2FpLXRyYW5zZm9ybWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFBVSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRCxPQUFPLEVBQUUscUJBQXFCLEVBQW1CLE1BQU0sYUFBYSxDQUFDO0FBMkRyRSxxQ0FBcUM7QUFDckMsTUFBTSxPQUFnQixpQkFBaUI7SUFXckMsWUFBWSxNQUFnQjtRQVRsQixxQkFBZ0IsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0IsaUJBQVksR0FBRyxNQUFNLENBQWE7WUFDMUMsS0FBSyxFQUFFLENBQUM7WUFDUixNQUFNLEVBQUUsQ0FBQztZQUNULEtBQUssRUFBRSxDQUFDO1NBQ1QsQ0FBQyxDQUFDO1FBQ08scUJBQWdCLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBSXpDLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxjQUFjLEdBQUc7WUFDcEIsWUFBWSxFQUFFLENBQUM7WUFDZixXQUFXLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUN2QixXQUFXLEVBQUUsRUFBRSxFQUFFLGtDQUFrQztZQUNuRCxVQUFVLEVBQUUsS0FBSztTQUNsQixDQUFDO0lBQ0osQ0FBQztJQUlELFNBQVMsQ0FBQyxLQUF5QjtRQUNqQyxNQUFNLE1BQU0sR0FBRyxxQkFBcUIsQ0FBSSxJQUFXLENBQUMsQ0FBQztRQUVyRCxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUNuQyxJQUFJLFVBQVUsS0FBSyxJQUFJLElBQUksVUFBVSxLQUFLLFNBQVM7Z0JBQUUsT0FBTztZQUU1RCxJQUFJLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLGdCQUF3QixD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