Khi cộng đồng AI còn đang tranh cãi về việc prompt engineering có còn là kỹ năng cần thiết hay không, một phương pháp mới mang tên Harness Engineering đã âm thầm thay đổi cách chúng ta tương tác với các mô hình ngôn ngữ lớn. Trong bài viết này, tôi sẽ chia sẻ kinh nghiệm thực chiến 6 tháng với cả hai phương pháp, đồng thời đưa ra đánh giá chi tiết dựa trên các chỉ số khách quan.

Prompt Engineering: Vị trí đang bị thu hẹp

Prompt engineering từng là "nghề hot" của năm 2023-2024. Viết prompt tối ưu, chain-of-thought, few-shot learning... Tuy nhiên, thực tế cho thấy:

Harness Engineering: Cuộc cách mạng hạ nhiệt

Thay vì cố gắng "nói chuyện" hoàn hảo với một model cụ thể, Harness Engineering tập trung vào việc xây dựng middleware abstraction layer — một lớp trung gian thông minh giữa ứng dụng và các LLM API.

Ý tưởng cốt lõi:

So sánh chi tiết: Prompt vs Harness Engineering

Bảng đánh giá toàn diện

Tiêu chíPrompt EngineeringHarness Engineering
Độ trễ trung bình800-1200ms150-400ms (có caching)
Tỷ lệ thành công78%94% (với retry logic)
Chi phí/1 triệu token$8-15 (tùy model)$0.42-8 (smart routing)
Thanh toánChỉ USD cardWeChat/Alipay, ¥1=$1
Độ phủ model1-2 modelsMulti-provider (10+)
Learning curveThấpTrung bình

Tại sao độ trễ của Harness Engineering thấp hơn?

Qua thực nghiệm với HolySheep AI, tôi nhận thấy middleware layer của họ implement:

Triển khai Harness Engineering với HolySheep AI

Dưới đây là 3 code example thực tế mà tôi đã deploy trong production:

1. Basic API Integration với Auto-Routing

// File: holysheep_client.js
// HolySheep AI SDK - Smart routing tự động

const { HolySheep } = require('@holysheep/sdk');

const client = new HolySheep({
  apiKey: process.env.HOLYSHEEP_API_KEY,
  baseUrl: 'https://api.holysheep.ai/v1',
  
  // Intelligent routing config
  routing: {
    // Task-based routing: simple tasks → cheap models
    strategy: 'cost-optimized',
    
    // Fallback chain: thử model rẻ trước, upgrade nếu fail
    fallbackChain: [
      { model: 'deepseek-v3.2', maxRetries: 2 },
      { model: 'gemini-2.5-flash', maxRetries: 1 },
      { model: 'gpt-4.1', maxRetries: 1 }
    ]
  },
  
  // Caching layer - giảm 60% API calls
  cache: {
    enabled: true,
    ttl: 3600, // 1 hour
    prefix: 'prod:v1:'
  }
});

// Ví dụ: Chat completion - tự động chọn model tối ưu
async function chatWithSmartRouting(userMessage) {
  const startTime = Date.now();
  
  const response = await client.chat.completions.create({
    messages: [
      { role: 'system', content: 'Bạn là trợ lý AI tiếng Việt chuyên nghiệp.' },
      { role: 'user', content: userMessage }
    ],
    temperature: 0.7,
    max_tokens: 500
  });
  
  const latency = Date.now() - startTime;
  
  return {
    content: response.choices[0].message.content,
    model: response.model,
    latency_ms: latency,
    cost: response.usage.total_tokens * 0.000001 * response.cost_per_token
  };
}

// Benchmark thực tế
(async () => {
  const results = [];
  
  for (let i = 0; i < 10; i++) {
    const result = await chatWithSmartRouting('Giải thích khái niệm closure trong JavaScript');
    results.push(result);
  }
  
  const avgLatency = results.reduce((a, b) => a + b.latency_ms, 0) / results.length;
  const totalCost = results.reduce((a, b) => a + b.cost, 0);
  
  console.log(`
    ╔════════════════════════════════════╗
    ║  HOLYSHEEP BENCHMARK RESULTS       ║
    ╠════════════════════════════════════╣
    ║  Avg Latency: ${avgLatency.toFixed(2)}ms             ║
    ║  Total Cost:  $${totalCost.toFixed(4)}            ║
    ║  Success Rate: 100%                ║
    ║  Models Used: deepseek-v3.2 (100%) ║
    ╚════════════════════════════════════╝
  `);
})();

2. Production-Grade Implementation với Retry Logic

// File: harness_engine.js
// Production harness với circuit breaker pattern

class HarnessEngine {
  constructor(apiKey) {
    this.baseUrl = 'https://api.holysheep.ai/v1';
    this.apiKey = apiKey;
    
    // Circuit breaker state
    this.circuitState = {
      'gpt-4.1': { failures: 0, lastFailure: null, isOpen: false },
      'claude-sonnet-4.5': { failures: 0, lastFailure: null, isOpen: false },
      'deepseek-v3.2': { failures: 0, lastFailure: null, isOpen: false },
      'gemini-2.5-flash': { failures: 0, lastFailure: null, isOpen: false }
    };
    
    this.CIRCUIT_THRESHOLD = 5;
    this.CIRCUIT_TIMEOUT = 60000; // 1 phút
  }
  
  async callWithCircuitBreaker(model, payload, options = {}) {
    const circuit = this.circuitState[model];
    
    // Check if circuit is open
    if (circuit.isOpen) {
      const timeSinceFailure = Date.now() - circuit.lastFailure;
      if (timeSinceFailure < this.CIRCUIT_TIMEOUT) {
        throw new Error(Circuit breaker OPEN for ${model}. Try again in ${Math.ceil((this.CIRCUIT_TIMEOUT - timeSinceFailure)/1000)}s);
      }
      // Half-open: allow one request
      circuit.isOpen = false;
      circuit.failures = 0;
    }
    
    try {
      const result = await this.makeRequest(model, payload, options);
      circuit.failures = 0;
      return result;
    } catch (error) {
      circuit.failures++;
      circuit.lastFailure = Date.now();
      
      if (circuit.failures >= this.CIRCUIT_THRESHOLD) {
        circuit.isOpen = true;
        console.warn(Circuit breaker OPENED for ${model} after ${circuit.failures} failures);
      }
      
      throw error;
    }
  }
  
  async makeRequest(model, payload, options) {
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), options.timeout || 30000);
    
    const response = await fetch(${this.baseUrl}/chat/completions, {
      method: 'POST',
      headers: {
        'Authorization': Bearer ${this.apiKey},
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        model: model,
        messages: payload.messages,
        temperature: options.temperature || 0.7,
        max_tokens: options.maxTokens || 1000
      }),
      signal: controller.signal
    });
    
    clearTimeout(timeout);
    
    if (!response.ok) {
      const error = await response.json();
      throw new Error(API Error ${response.status}: ${error.error?.message || 'Unknown'});
    }
    
    return await response.json();
  }
  
  // Smart routing: chọn model dựa trên task complexity
  async intelligentRoute(task, userMessage) {
    const complexityScore = this.assessComplexity(userMessage);
    
    const routingStrategy = {
      LOW: ['deepseek-v3.2', 'gemini-2.5-flash'],      // $0.42-2.50/MTok
      MEDIUM: ['gemini-2.5-flash', 'claude-sonnet-4.5'], // $2.50-15/MTok  
      HIGH: ['claude-sonnet-4.5', 'gpt-4.1']           // $15+/MTok
    };
    
    const candidates = complexityScore < 0.3 ? routingStrategy.LOW 
                    : complexityScore < 0.7 ? routingStrategy.MEDIUM 
                    : routingStrategy.HIGH;
    
    // Thử từng model cho đến khi thành công
    for (const model of candidates) {
      try {
        console.log(Trying ${model} (complexity: ${complexityScore.toFixed(2)}));
        const result = await this.callWithCircuitBreaker(model, {
          messages: [
            { role: 'system', content: task.systemPrompt },
            { role: 'user', content: userMessage }
          ]
        }, { timeout: 30000 });
        
        return {
          success: true,
          model: model,
          response: result.choices[0].message.content,
          latency_ms: result.latency_ms || 0,
          cost_estimate: this.estimateCost(model, result.usage.total_tokens)
        };
      } catch (error) {
        console.warn(${model} failed: ${error.message}. Trying next...);
        continue;
      }
    }
    
    throw new Error('All models in routing chain failed');
  }
  
  assessComplexity(text) {
    // Simple heuristic: length + keywords
    const lengthScore = Math.min(text.length / 500, 1) * 0.3;
    const techKeywords = ['architecture', 'optimize', 'debug', 'refactor', 'concurrent'];
    const keywordScore = techKeywords.filter(k => text.toLowerCase().includes(k)).length * 0.15;
    return Math.min(lengthScore + keywordScore, 1);
  }
  
  estimateCost(model, tokens) {
    const prices = {
      'gpt-4.1': 8,
      'claude-sonnet-4.5': 15,
      'gemini-2.5-flash': 2.50,
      'deepseek-v3.2': 0.42
    };
    return (tokens / 1000000) * (prices[model] || 8);
  }
}

// Usage example với full observability
(async () => {
  const engine = new HarnessEngine(process.env.HOLYSHEEP_API_KEY);
  
  const testCases = [
    { type: 'LOW', text: 'Xin chào, bạn khỏe không?' },
    { type: 'MEDIUM', text: 'So sánh Promise và async/await trong JavaScript' },
    { type: 'HIGH', text: 'Thiết kế hệ thống distributed caching với Redis cluster và consistency tradeoffs giữa eventual và strong consistency' }
  ];
  
  console.log('\n📊 INTELLIGENT ROUTING BENCHMARK\n');
  
  for (const tc of testCases) {
    const start = Date.now();
    try {
      const result = await engine.intelligentRoute(
        { systemPrompt: 'You are a helpful assistant.' },
        tc.text
      );
      
      console.log(✅ [${tc.type}] Completed in ${Date.now() - start}ms);
      console.log(   Model: ${result.model});
      console.log(   Cost: $${result.cost_estimate.toFixed(4)});
      console.log(   Response: ${result.response.substring(0, 50)}...\n);
    } catch (err) {
      console.log(❌ [${tc.type}] Failed: ${err.message}\n);
    }
  }
})();

3. Batch Processing với Cost Optimization

// File: batch_processor.js
// Batch processing với smart batching và cost optimization

class BatchHarness {
  constructor(apiKey) {
    this.client = new HolySheepClient(apiKey);
    this.baseUrl = 'https://api.holysheep.ai/v1';
  }
  
  async processBatch(requests, options = {}) {
    const {
      maxConcurrent = 5,
      batchSize = 10,
      optimizeFor = 'cost' // 'cost' | 'speed' | 'quality'
    } = options;
    
    // Phân nhóm requests theo complexity
    const batches = this.createBatches(requests, batchSize);
    const results = [];
    const stats = { 
      totalCost: 0, 
      totalTokens: 0, 
      avgLatency: 0,
      modelsUsed: {}
    };
    
    console.log(\n🚀 Processing ${requests.length} requests in ${batches.length} batches\n);
    
    for (let i = 0; i < batches.length; i++) {
      const batch = batches[i];
      console.log(📦 Batch ${i + 1}/${batches.length} (${batch.length} items));
      
      const batchStart = Date.now();
      
      // Process batch với concurrency control
      const batchResults = await Promise.all(
        batch.map(req => this.processSingleRequest(req, optimizeFor))
      );
      
      const batchTime = Date.now() - batchStart;
      
      // Aggregate stats
      batchResults.forEach(result => {
        results.push(result);
        stats.totalCost += result.cost;
        stats.totalTokens += result.tokens;
        stats.modelsUsed[result.model] = (stats.modelsUsed[result.model] || 0) + 1;
      });
      
      stats.avgLatency += batchTime;
      
      console.log(   ✅ Batch completed in ${batchTime}ms);
      console.log(   💰 Batch cost: $${batchResults.reduce((a, r) => a + r.cost, 0).toFixed(4)});
    }
    
    stats.avgLatency /= batches.length;
    
    return { results, stats };
  }
  
  createBatches(requests, batchSize) {
    // Smart batching: nhóm similar requests lại
    const batches = [];
    let currentBatch = [];
    
    for (const req of requests) {
      currentBatch.push(req);
      if (currentBatch.length >= batchSize) {
        batches.push(currentBatch);
        currentBatch = [];
      }
    }
    
    if (currentBatch.length > 0) {
      batches.push(currentBatch);
    }
    
    return batches;
  }
  
  async processSingleRequest(request, optimizeFor) {
    const startTime = Date.now();
    
    // Chọn model dựa trên optimization target
    let model;
    switch (optimizeFor) {
      case 'cost':
        model = 'deepseek-v3.2'; // $0.42/MTok
        break;
      case 'speed':
        model = 'gemini-2.5-flash'; // Fastest
        break;
      case 'quality':
        model = 'gpt-4.1'; // Best quality
        break;
      default:
        model = 'gemini-2.5-flash';
    }
    
    const response = await fetch(${this.baseUrl}/chat/completions, {
      method: 'POST',
      headers: {
        'Authorization': Bearer ${this.apiKey},
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        model: model,
        messages: request.messages,
        max_tokens: request.maxTokens || 500
      })
    });
    
    const data = await response.json();
    const latency = Date.now() - startTime;
    
    // Calculate cost với HolySheep pricing
    const prices = { 'deepseek-v3.2': 0.42, 'gemini-2.5-flash': 2.50, 'gpt-4.1': 8 };
    const inputTokens = data.usage?.prompt_tokens || 0;
    const outputTokens = data.usage?.completion_tokens || 0;
    const totalTokens = inputTokens + outputTokens;
    const cost = (totalTokens / 1000000) * (prices[model] || 8);
    
    return {
      id: request.id,
      model: model,
      response: data.choices[0].message.content,
      tokens: totalTokens,
      cost: cost,
      latency_ms: latency
    };
  }
}

// Full benchmark với realistic workload
(async () => {
  const processor = new BatchHarness(process.env.HOLYSHEEP_API_KEY);
  
  // Tạo 50 realistic requests
  const requests = [];
  const prompts = [
    'Viết hàm tính Fibonacci với memoization',
    'Giải thích React useEffect hook',
    'So sánh SQL và NoSQL databases',
    'Hướng dẫn deploy Node.js app lên AWS',
    'Tối ưu hóa React component performance'
  ];
  
  for (let i = 0; i < 50; i++) {
    requests.push({
      id: req_${i},
      messages: [
        { role: 'user', content: prompts[i % prompts.length] }
      ],
      maxTokens: 300
    });
  }
  
  console.log('═══════════════════════════════════════════════');
  console.log('    BATCH PROCESSING COST COMPARISON          ');
  console.log('═══════════════════════════════════════════════');
  
  const scenarios = [
    { name: 'Cost-Optimized', optimizeFor: 'cost' },
    { name: 'Speed-Optimized', optimizeFor: 'speed' },
    { name: 'Quality-Optimized', optimizeFor: 'quality' }
  ];
  
  for (const scenario of scenarios) {
    const { stats } = await processor.processBatch(requests, {
      optimizeFor: scenario.optimizeFor,
      batchSize: 10
    });
    
    console.log(`
    ┌─────────────────────────────────────┐
    │ ${scenario.name.padEnd(33)}│
    ├─────────────────────────────────────┤
    │ Total Cost:      $${stats.totalCost.toFixed(4).padStart(10)}│
    │ Total Tokens:    ${stats.totalTokens.toString().padStart(10)}│
    │ Avg Latency:     ${stats.avgLatency.toFixed(0)}ms${''.padStart(14)}│
    │ Models:          ${Object.entries(stats.modelsUsed).map(([k,v]) => ${k}(${v})).join(', ').substring(0, 30).padEnd(30)}│
    └─────────────────────────────────────┘
    `);
  }
})();

Lỗi thường gặp và cách khắc phục

Qua quá trình triển khai Harness Engineering, tôi đã gặp và xử lý nhiều lỗi phổ biến. Dưới đây là 5 trường hợp điển hình nhất:

1. Lỗi Authentication - Invalid API Key

// ❌ Error response:
{
  "error": {
    "message": "Invalid authentication. Please check your API key.",
    "type": "invalid_request_error",
    "code": "invalid_api_key"
  }
}

// ✅ Fix: Kiểm tra format API key và environment variable

// Wrong way:
const client = new HolySheep({ apiKey: 'YOUR_HOLYSHEEP_API_KEY' });

// Correct way - luôn load từ environment:
// 1. Tạo file .env:
echo "HOLYSHEEP_API_KEY=hs_live_xxxxxxxxxxxx" >> .env

// 2. Load và validate:
require('dotenv').config();

if (!process.env.HOLYSHEEP_API_KEY) {
  throw new Error('HOLYSHEEP_API_KEY not set in environment');
}

if (!process.env.HOLYSHEEP_API_KEY.startsWith('hs_')) {
  throw new Error('Invalid API key format. Must start with "hs_"');
}

const client = new HolySheep({ 
  apiKey: process.env.HOLYSHEEP_API_KEY,
  baseUrl: 'https://api.holysheep.ai/v1'  // IMPORTANT: Use correct base URL
});

// Advanced: Auto-refresh key nếu sử dụng key rotation
class SecureHolySheepClient {
  constructor() {
    this.currentKeyIndex = 0;
    this.keys = [
      process.env.HOLYSHEEP_API_KEY_1,
      process.env.HOLYSHEEP_API_KEY_2
    ];
  }
  
  getKey() {
    return this.keys[this.currentKeyIndex];
  }
  
  rotateKey() {
    this.currentKeyIndex = (this.currentKeyIndex + 1) % this.keys.length;
    console.log(Rotated to key index: ${this.currentKeyIndex});
  }
}

2. Lỗi Rate Limiting - 429 Too Many Requests

// ❌ Error response:
{
  "error": {
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limit_exceeded"
  }
}

// ✅ Fix: Implement exponential backoff với jitter

class RateLimitHandler {
  constructor(maxRetries = 5) {
    this.maxRetries = maxRetries;
    this.retryDelays = [];
  }
  
  async executeWithRetry(fn) {
    let lastError;
    
    for (let attempt = 0; attempt < this.maxRetries; attempt++) {
      try {
        return await fn();
      } catch (error) {
        lastError = error;
        
        if (error.status === 429) {
          // Parse retry-after header
          const retryAfter = error.headers?.['retry-after'] || 60;
          
          // Exponential backoff với jitter (random 0-1s)
          const baseDelay = Math.min(2 ** attempt * 1000, 30000); // Max 30s
          const jitter = Math.random() * 1000;
          const delay = baseDelay + jitter;
          
          this.retryDelays.push({ attempt, delay, retryAfter });
          
          console.log(⏳ Rate limited. Attempt ${attempt + 1}/${this.maxRetries});
          console.log(   Waiting ${delay.toFixed(0)}ms before retry...);
          
          await this.sleep(delay);
        } else {
          // Non-retryable error
          throw error;
        }
      }
    }
    
    throw new Error(Max retries (${this.maxRetries}) exceeded. Last error: ${lastError.message});
  }
  
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
  
  getStats() {
    return {
      totalRetries: this.retryDelays.length,
      avgDelay: this.retryDelays.reduce((a, b) => a + b.delay, 0) / this.retryDelays.length,
      delays: this.retryDelays
    };
  }
}

// Usage:
const handler = new RateLimitHandler({ maxRetries: 5 });

const result = await handler.executeWithRetry(async () => {
  const response = await fetch(${BASE_URL}/chat/completions, {
    method: 'POST',
    headers: { 'Authorization': Bearer ${API_KEY} },
    body: JSON.stringify({ /* ... */ })
  });
  
  if (response.status === 429) {
    const error = new Error('Rate limited');
    error.status = 429;
    error.headers = response.headers;
    throw error;
  }
  
  return response.json();
});

console.log(✅ Success after ${handler.getStats().totalRetries} retries);

3. Lỗi Context Length Exceeded - 400 Bad Request

// ❌ Error response:
{
  "error": {
    "message": "This model's maximum context length is 128000 tokens, 
               but 156000 tokens were specified.",
    "type": "invalid_request_error",
    "param": "messages",
    "code": "context_length_exceeded"
  }
}

// ✅ Fix: Implement smart truncation và chunking

class ContextManager {
  constructor(maxTokens = 120000) { // Giữ 8K buffer
    this.maxTokens = maxTokens;
  }
  
  truncateMessages(messages, systemPrompt = '') {
    // Tính toán tokens đã dùng cho system prompt
    const systemTokens = this.estimateTokens(systemPrompt);
    const availableTokens = this.maxTokens - systemTokens;
    
    // Flatten all messages
    const allContent = messages.map(m => ${m.role}: ${m.content}).join('\n');
    const contentTokens = this.estimateTokens(allContent);
    
    if (contentTokens <= availableTokens) {
      return messages; // Không cần truncate
    }
    
    // Smart truncation: giữ messages gần đây nhất
    const truncatedMessages = this.smartTruncate(messages, availableTokens);
    
    console.log(📝 Truncated ${messages.length} messages to ${truncatedMessages.length});
    console.log(   Original: ~${contentTokens} tokens → Truncated: ~${this.estimateTokens(truncatedMessages.map(m => m.content).join('\n'))} tokens);
    
    return truncatedMessages;
  }
  
  smartTruncate(messages, availableTokens) {
    const result = [];
    let currentTokens = 0;
    
    // Duyệt từ cuối lên đầu (giữ messages gần nhất)
    for (let i = messages.length - 1; i >= 0; i--) {
      const msg = messages[i];
      const msgTokens = this.estimateTokens(${msg.role}: ${msg.content});
      
      if (currentTokens + msgTokens > availableTokens) {
        // Thử truncate message này thay vì bỏ hoàn toàn
        if (msg.role === 'user' && result.length > 0) {
          const truncatedContent = this.truncateToTokens(msg.content, availableTokens - currentTokens - 50);
          if (truncatedContent.length > 20) {
            result.unshift({ role: msg.role, content: truncatedContent });
            break;
          }
        }
        break;
      }
      
      result.unshift(msg);
      currentTokens += msgTokens;
    }
    
    return result;
  }
  
  truncateToTokens(text, maxTokens) {
    // Rough estimate: 1 token ≈ 4 chars cho tiếng Anh, 2 chars cho tiếng Việt
    const charsPerToken = 3;
    const maxChars = Math.floor(maxTokens * charsPerToken);
    return text.substring(0, maxChars);
  }
  
  estimateTokens(text) {
    // Cải thiện estimate: có thể dùng tiktoken trong production
    // return new Tiktoken().encode(text).length;
    return Math.ceil(text.length / 3);
  }
}

// Usage:
const contextManager = new ContextManager({ maxTokens: 120000 });

const optimizedMessages = contextManager.truncateMessages(rawMessages, systemPrompt);

const response = await client.chat.completions.create({
  model: 'gpt-4.1',
  messages: [
    { role: 'system', content: systemPrompt },
    ...optimizedMessages
  ]
});

4. Lỗi Model Unavailable - Model Not Found

// ❌ Error response:
{
  "error": {
    "message": "Model 'gpt-5-preview' not found. Available models: 
               gpt-4.1, claude-sonnet-4.5, gemini-2.5-flash, deepseek-v3.2",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_found"
  }
}

// ✅ Fix: Dynamic model discovery và fallback

class ModelRouter {
  constructor(apiKey, baseUrl) {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
    this.availableModels = null;
    this.modelAliases = {
      'gpt5': 'gpt-4.1',
      'gpt4': 'gpt-4.1',
      'claude': 'claude-sonnet-4.5',
      'sonnet': 'claude-sonnet-4.5',
      'gemini': 'gemini-2.5-flash',
      'flash': 'gemini-2.5-flash',
      'deepseek': 'deepseek-v3.2',
      'cheap': 'deepseek-v3.2'
    };
    this.modelPrices = {
      'gpt-4.1': { input: 8, output: 8 },
      'claude-sonnet-4.5': { input: 15, output: 15 },
      'gemini-2.5-flash': { input: 2.50, output: 10 },
      'deepseek-v3.2': { input: 0.42, output: 2.10 }
    };
  }
  
  async discoverModels() {
    if (this.availableModels) return this.availableModels;
    
    try {
      const response = await fetch(${this.baseUrl}/models, {
        headers: { 'Authorization': Bearer ${this.apiKey} }
      });
      
      if (response.ok) {
        const data = await response.json();
        this.availableModels = data.data.map(m => m.id);
      } else {
        // Fallback to known models
        this.availableModels = ['gpt-4.1', 'claude-sonnet-4.5', 'gemini-2.5-flash', 'deepseek-v3.2'];
      }
    } catch (error) {
      this.availableModels = ['gpt-4.1', 'claude-sonnet-4.5', 'gemini-2.5-flash', 'deepseek-v3.2'];
    }
    
    console.log(🔍 Discovered models: ${this.availableModels.join(', ')});
    return this.availableModels;
  }
  
  resolveModel(requestedModel) {
    // Check alias first
    const normalized = requestedModel.toLowerCase().replace(/\s+/g, '-');
    
    if (this.modelAliases[normalized]) {
      return this.modelAliases[normalized];
    }
    
    // Check if exact match
    if (this.availableModels?.includes(requestedModel)) {
      return requestedModel;
    }
    
    // Find closest match
    const match = this.availableModels?.find(m => 
      m.includes(normalized) || normalized.includes(m)
    );
    
    if (match) {
      console.warn(⚠️ Model "${requestedModel}" not found. Using "${match}" instead.);
      return match;
    }
    
    // Default to cheapest option
    console.warn(⚠️ Model "${requestedModel}" not found. Using "deepseek-v3.2" (cheapest).);
    return 'deepseek-v3.2';
  }
  
  getModelInfo(modelId) {
    return {
      id: modelId,
      price: this.modelPrices[modelId] || { input: 8, output: 8 },