import { generateObject } from "ai";
import { createContainer } from "awilix";
import {
  resolveAiProviderIdFromEnv,
  resolveFirstConfiguredOpenCodeProvider,
  resolveOpenCodeModel,
  requireOpenCodeProviderApiKey,
  resolveOpenCodeProviderId,
  isOpenCodeProviderId
} from "@open-mercato/shared/lib/ai/opencode-provider";
import {
  AiModelFactoryError,
  createModelFactory
} from "@open-mercato/ai-assistant/modules/ai_assistant/lib/model-factory";
import { joinProviderModel } from "@open-mercato/shared/lib/ai/model-id";
import { extractionOutputSchema } from "../data/validators.js";
function asAiModel(model) {
  return model;
}
function resolveExtractionProviderId() {
  const canonicalProvider = (process.env.OM_AI_PROVIDER ?? "").trim();
  if (canonicalProvider.length > 0 && !isOpenCodeProviderId(canonicalProvider.toLowerCase())) {
    throw new Error(
      `[internal] OM_AI_PROVIDER="${canonicalProvider}" is set but that provider is not configured (no API key found), and the legacy inbox_ops extraction fallback only supports anthropic, openai, or google. Set the provider's API key (e.g. OPENROUTER_API_KEY for openrouter) so the unified model factory can serve it, or switch OM_AI_PROVIDER to a configured native provider.`
    );
  }
  const explicit = canonicalProvider || (process.env.OPENCODE_PROVIDER ?? "").trim();
  if (explicit.length > 0) {
    return resolveAiProviderIdFromEnv(process.env);
  }
  const firstConfiguredProvider = resolveFirstConfiguredOpenCodeProvider();
  if (firstConfiguredProvider) {
    return firstConfiguredProvider;
  }
  return resolveOpenCodeProviderId(void 0);
}
async function createStructuredModel(providerId, apiKey, modelId) {
  switch (providerId) {
    case "anthropic": {
      const { createAnthropic } = await import("@ai-sdk/anthropic");
      return asAiModel(createAnthropic({ apiKey })(modelId));
    }
    case "openai": {
      const { createOpenAI } = await import("@ai-sdk/openai");
      return asAiModel(createOpenAI({ apiKey })(modelId));
    }
    case "google": {
      const { createGoogleGenerativeAI } = await import("@ai-sdk/google");
      return asAiModel(createGoogleGenerativeAI({ apiKey })(modelId));
    }
    default:
      throw new Error(`Unsupported provider: ${providerId}`);
  }
}
async function withTimeout(operation, timeoutMs, timeoutMessage) {
  let timeoutHandle;
  const timeoutPromise = new Promise((_, reject) => {
    timeoutHandle = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
  });
  try {
    return await Promise.race([operation, timeoutPromise]);
  } finally {
    if (timeoutHandle) {
      clearTimeout(timeoutHandle);
    }
  }
}
const __inboxOpsLlmProviderInternal = {
  createModelFactory,
  createContainer
};
function tryFactoryResolution(input) {
  let factory;
  try {
    const container = __inboxOpsLlmProviderInternal.createContainer();
    factory = __inboxOpsLlmProviderInternal.createModelFactory(container);
  } catch {
    return null;
  }
  try {
    const resolution = factory.resolveModel({
      moduleId: input.moduleId ?? "inbox_ops",
      callerOverride: input.modelOverride ?? void 0
    });
    return {
      model: asAiModel(resolution.model),
      modelWithProvider: joinProviderModel(resolution.providerId, resolution.modelId)
    };
  } catch (err) {
    if (err instanceof AiModelFactoryError) {
      return null;
    }
    throw err;
  }
}
async function resolveConfiguredStructuredModel(input = {}) {
  const fromFactory = tryFactoryResolution(input);
  if (fromFactory) return fromFactory;
  const providerId = resolveExtractionProviderId();
  const apiKey = requireOpenCodeProviderApiKey(providerId);
  const modelConfig = resolveOpenCodeModel(providerId, {
    overrideModel: input.modelOverride
  });
  const model = await createStructuredModel(providerId, apiKey, modelConfig.modelId);
  return { model, modelWithProvider: modelConfig.modelWithProvider };
}
async function runExtractionWithConfiguredProvider(input) {
  const { model, modelWithProvider } = await resolveConfiguredStructuredModel({
    moduleId: "inbox_ops",
    modelOverride: input.modelOverride
  });
  const result = await withTimeout(
    generateObject({
      model,
      schema: extractionOutputSchema,
      system: input.systemPrompt,
      prompt: input.userPrompt,
      temperature: 0
    }),
    input.timeoutMs,
    `LLM extraction timed out after ${input.timeoutMs}ms`
  );
  return {
    object: result.object,
    totalTokens: Number(result.usage?.totalTokens ?? 0) || 0,
    modelWithProvider
  };
}
export {
  __inboxOpsLlmProviderInternal,
  createStructuredModel,
  resolveConfiguredStructuredModel,
  resolveExtractionProviderId,
  runExtractionWithConfiguredProvider,
  withTimeout
};
//# sourceMappingURL=llmProvider.js.map
