import { fileURLToPath as __fileURLToPath } from 'url';
import { dirname as __pathDirname } from 'path';
const __filename = __fileURLToPath(import.meta.url);
const __dirname = __pathDirname(__filename);
import Anthropic from "@anthropic-ai/sdk";
import { logger } from "../monitoring/logger.js";
class AnthropicLLMProvider {
  client;
  model;
  temperature;
  maxRetries;
  timeout;
  constructor(config) {
    this.client = new Anthropic({
      apiKey: config.apiKey
    });
    this.model = config.model || "claude-3-haiku-20240307";
    this.temperature = config.temperature ?? 0.3;
    this.maxRetries = config.maxRetries ?? 2;
    this.timeout = config.timeout ?? 3e4;
    logger.info("AnthropicLLMProvider initialized", {
      model: this.model,
      temperature: this.temperature
    });
  }
  /**
   * Analyze a prompt using the Anthropic API
   */
  async analyze(prompt, maxTokens) {
    const startTime = Date.now();
    let lastError = null;
    for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
      try {
        const response = await this.makeRequest(prompt, maxTokens);
        logger.debug("LLM analysis completed", {
          model: this.model,
          promptLength: prompt.length,
          responseLength: response.length,
          durationMs: Date.now() - startTime,
          attempt
        });
        return response;
      } catch (error) {
        lastError = error instanceof Error ? error : new Error(String(error));
        if (this.isRetryableError(error) && attempt < this.maxRetries) {
          const backoffMs = Math.pow(2, attempt) * 1e3;
          logger.warn("LLM request failed, retrying", {
            attempt,
            backoffMs,
            error: lastError.message
          });
          await this.sleep(backoffMs);
          continue;
        }
        break;
      }
    }
    logger.error("LLM analysis failed after retries", lastError);
    throw lastError;
  }
  /**
   * Make the actual API request
   */
  async makeRequest(prompt, maxTokens) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), this.timeout);
    try {
      const response = await this.client.messages.create({
        model: this.model,
        max_tokens: maxTokens,
        temperature: this.temperature,
        messages: [
          {
            role: "user",
            content: prompt
          }
        ]
      });
      const textContent = response.content.find((c) => c.type === "text");
      if (!textContent || textContent.type !== "text") {
        throw new Error("No text content in response");
      }
      return textContent.text;
    } finally {
      clearTimeout(timeoutId);
    }
  }
  /**
   * Check if an error is retryable
   */
  isRetryableError(error) {
    if (error instanceof Anthropic.RateLimitError) {
      return true;
    }
    if (error instanceof Anthropic.APIConnectionError) {
      return true;
    }
    if (error instanceof Anthropic.InternalServerError) {
      return true;
    }
    if (error instanceof Error && error.name === "AbortError") {
      return true;
    }
    return false;
  }
  sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
}
class LocalFallbackProvider {
  async analyze(prompt, maxTokens) {
    const lines = prompt.split("\n").filter((l) => l.trim());
    const contentStart = lines.findIndex((l) => l.includes("Content:"));
    if (contentStart === -1 || lines.length < 3) {
      return "Context summary not available (local mode)";
    }
    const content = lines.slice(contentStart + 1).join("\n");
    const sentences = content.split(/[.!?]+/).filter((s) => s.trim().length > 10);
    const maxChars = maxTokens * 4;
    let summary = "";
    for (const sentence of sentences.slice(0, 5)) {
      if (summary.length + sentence.length > maxChars) break;
      summary += sentence.trim() + ". ";
    }
    return summary.trim() || "Context available (use LLM API for detailed analysis)";
  }
}
function createLLMProvider() {
  if (process.env["STACKMEMORY_LOCAL"] === "true" || process.env["LOCAL_ONLY"] === "true") {
    logger.info("LOCAL mode - using heuristic summarization");
    return new LocalFallbackProvider();
  }
  const apiKey = process.env["ANTHROPIC_API_KEY"];
  if (!apiKey) {
    logger.info(
      "No ANTHROPIC_API_KEY found, LLM retrieval will use heuristics"
    );
    return new LocalFallbackProvider();
  }
  return new AnthropicLLMProvider({
    apiKey,
    model: process.env["ANTHROPIC_MODEL"] || "claude-3-haiku-20240307",
    temperature: parseFloat(process.env["ANTHROPIC_TEMPERATURE"] || "0.3")
  });
}
export {
  AnthropicLLMProvider,
  LocalFallbackProvider,
  createLLMProvider
};
//# sourceMappingURL=llm-provider.js.map
