import { f as isRecord } from "./utils-CcH8KYHm.js";
import { D as resolveImplicitBedrockProvider, E as normalizeProviders, Nt as resolveCoderClawAgentDir, O as resolveImplicitCopilotProvider, k as resolveImplicitProviders } from "./model-selection-Cu-UzQaa.js";
import { i as loadConfig } from "./io-B0vHiKay.js";
import path from "node:path";
import fs from "node:fs/promises";
import { AuthStorage, AuthStorage as AuthStorage$1, ModelRegistry, ModelRegistry as ModelRegistry$1 } from "@mariozechner/pi-coding-agent";

//#region src/agents/models-config.ts
const DEFAULT_MODE = "merge";
function mergeProviderModels(implicit, explicit) {
	const implicitModels = Array.isArray(implicit.models) ? implicit.models : [];
	const explicitModels = Array.isArray(explicit.models) ? explicit.models : [];
	if (implicitModels.length === 0) return {
		...implicit,
		...explicit
	};
	const getId = (model) => {
		if (!model || typeof model !== "object") return "";
		const id = model.id;
		return typeof id === "string" ? id.trim() : "";
	};
	const seen = new Set(explicitModels.map(getId).filter(Boolean));
	const mergedModels = [...explicitModels, ...implicitModels.filter((model) => {
		const id = getId(model);
		if (!id) return false;
		if (seen.has(id)) return false;
		seen.add(id);
		return true;
	})];
	return {
		...implicit,
		...explicit,
		models: mergedModels
	};
}
function mergeProviders(params) {
	const out = params.implicit ? { ...params.implicit } : {};
	for (const [key, explicit] of Object.entries(params.explicit ?? {})) {
		const providerKey = key.trim();
		if (!providerKey) continue;
		const implicit = out[providerKey];
		out[providerKey] = implicit ? mergeProviderModels(implicit, explicit) : explicit;
	}
	return out;
}
async function readJson(pathname) {
	try {
		const raw = await fs.readFile(pathname, "utf8");
		return JSON.parse(raw);
	} catch {
		return null;
	}
}
async function ensureCoderClawModelsJson(config, agentDirOverride) {
	const cfg = config ?? loadConfig();
	const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveCoderClawAgentDir();
	const explicitProviders = cfg.models?.providers ?? {};
	const providers = mergeProviders({
		implicit: await resolveImplicitProviders({
			agentDir,
			explicitProviders
		}),
		explicit: explicitProviders
	});
	const implicitBedrock = await resolveImplicitBedrockProvider({
		agentDir,
		config: cfg
	});
	if (implicitBedrock) {
		const existing = providers["amazon-bedrock"];
		providers["amazon-bedrock"] = existing ? mergeProviderModels(implicitBedrock, existing) : implicitBedrock;
	}
	const implicitCopilot = await resolveImplicitCopilotProvider({ agentDir });
	if (implicitCopilot && !providers["github-copilot"]) providers["github-copilot"] = implicitCopilot;
	if (Object.keys(providers).length === 0) return {
		agentDir,
		wrote: false
	};
	const mode = cfg.models?.mode ?? DEFAULT_MODE;
	const targetPath = path.join(agentDir, "models.json");
	let mergedProviders = providers;
	let existingRaw = "";
	if (mode === "merge") {
		const existing = await readJson(targetPath);
		if (isRecord(existing) && isRecord(existing.providers)) mergedProviders = {
			...existing.providers,
			...providers
		};
	}
	const normalizedProviders = normalizeProviders({
		providers: mergedProviders,
		agentDir
	});
	const next = `${JSON.stringify({ providers: normalizedProviders }, null, 2)}\n`;
	try {
		existingRaw = await fs.readFile(targetPath, "utf8");
	} catch {
		existingRaw = "";
	}
	if (existingRaw === next) return {
		agentDir,
		wrote: false
	};
	await fs.mkdir(agentDir, {
		recursive: true,
		mode: 448
	});
	await fs.writeFile(targetPath, next, { mode: 384 });
	return {
		agentDir,
		wrote: true
	};
}

//#endregion
//#region src/agents/pi-model-discovery.ts
function createAuthStorage$1(AuthStorageLike, path) {
	const withFactory = AuthStorageLike;
	if (typeof withFactory.create === "function") return withFactory.create(path);
	return new AuthStorageLike(path);
}
function discoverAuthStorage(agentDir) {
	return createAuthStorage$1(AuthStorage, path.join(agentDir, "auth.json"));
}
function discoverModels(authStorage, agentDir) {
	return new ModelRegistry(authStorage, path.join(agentDir, "models.json"));
}

//#endregion
//#region src/agents/model-catalog.ts
let modelCatalogPromise = null;
let hasLoggedModelCatalogError = false;
const defaultImportPiSdk = () => Promise.resolve({
	AuthStorage: AuthStorage$1,
	ModelRegistry: ModelRegistry$1
});
let importPiSdk = defaultImportPiSdk;
const CODEX_PROVIDER = "openai-codex";
const OPENAI_CODEX_GPT53_MODEL_ID = "gpt-5.3-codex";
const OPENAI_CODEX_GPT53_SPARK_MODEL_ID = "gpt-5.3-codex-spark";
function applyOpenAICodexSparkFallback(models) {
	if (models.some((entry) => entry.provider === CODEX_PROVIDER && entry.id.toLowerCase() === OPENAI_CODEX_GPT53_SPARK_MODEL_ID)) return;
	const baseModel = models.find((entry) => entry.provider === CODEX_PROVIDER && entry.id.toLowerCase() === OPENAI_CODEX_GPT53_MODEL_ID);
	if (!baseModel) return;
	models.push({
		...baseModel,
		id: OPENAI_CODEX_GPT53_SPARK_MODEL_ID,
		name: OPENAI_CODEX_GPT53_SPARK_MODEL_ID
	});
}
function createAuthStorage(AuthStorageLike, path) {
	const withFactory = AuthStorageLike;
	if (typeof withFactory.create === "function") return withFactory.create(path);
	return new AuthStorageLike(path);
}
async function loadModelCatalog(params) {
	if (params?.useCache === false) modelCatalogPromise = null;
	if (modelCatalogPromise) return modelCatalogPromise;
	modelCatalogPromise = (async () => {
		const models = [];
		const sortModels = (entries) => entries.sort((a, b) => {
			const p = a.provider.localeCompare(b.provider);
			if (p !== 0) return p;
			return a.name.localeCompare(b.name);
		});
		try {
			await ensureCoderClawModelsJson(params?.config ?? loadConfig());
			await (await import("./pi-auth-json-DjIcKoN8.js")).ensurePiAuthJsonFromAuthProfiles(resolveCoderClawAgentDir());
			const piSdk = await importPiSdk();
			const agentDir = resolveCoderClawAgentDir();
			const { join } = await import("node:path");
			const authStorage = createAuthStorage(piSdk.AuthStorage, join(agentDir, "auth.json"));
			const registry = new piSdk.ModelRegistry(authStorage, join(agentDir, "models.json"));
			const entries = Array.isArray(registry) ? registry : registry.getAll();
			for (const entry of entries) {
				const id = String(entry?.id ?? "").trim();
				if (!id) continue;
				const provider = String(entry?.provider ?? "").trim();
				if (!provider) continue;
				const name = String(entry?.name ?? id).trim() || id;
				const contextWindow = typeof entry?.contextWindow === "number" && entry.contextWindow > 0 ? entry.contextWindow : void 0;
				const reasoning = typeof entry?.reasoning === "boolean" ? entry.reasoning : void 0;
				const input = Array.isArray(entry?.input) ? entry.input : void 0;
				models.push({
					id,
					name,
					provider,
					contextWindow,
					reasoning,
					input
				});
			}
			applyOpenAICodexSparkFallback(models);
			if (models.length === 0) modelCatalogPromise = null;
			return sortModels(models);
		} catch (error) {
			if (!hasLoggedModelCatalogError) {
				hasLoggedModelCatalogError = true;
				console.warn(`[model-catalog] Failed to load model catalog: ${String(error)}`);
			}
			modelCatalogPromise = null;
			if (models.length > 0) return sortModels(models);
			return [];
		}
	})();
	return modelCatalogPromise;
}
/**
* Check if a model supports image input based on its catalog entry.
*/
function modelSupportsVision(entry) {
	return entry?.input?.includes("image") ?? false;
}
/**
* Find a model in the catalog by provider and model ID.
*/
function findModelInCatalog(catalog, provider, modelId) {
	const normalizedProvider = provider.toLowerCase().trim();
	const normalizedModelId = modelId.toLowerCase().trim();
	return catalog.find((entry) => entry.provider.toLowerCase() === normalizedProvider && entry.id.toLowerCase() === normalizedModelId);
}

//#endregion
export { discoverModels as a, discoverAuthStorage as i, loadModelCatalog as n, ensureCoderClawModelsJson as o, modelSupportsVision as r, findModelInCatalog as t };