import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { init_write_file_atomic, writeTextAtomicSync } from "../infra/write-file-atomic.js";
import { init_paths, resolveModelsJsonPath } from "./paths.js";
import { existsSync, readFileSync } from "fs";
import { z } from "zod";
//#region src/config/models-json.ts
/**
* Models.json configuration types and schema
* 
* Supports custom providers and models (Ollama, vLLM, LM Studio, proxies)
* 
* File location: ~/.xopc/models.json (or XOPC_MODELS_JSON env var)
*/
function validateModelsConfig(config) {
	const errors = [];
	const result = ModelsJsonSchema.safeParse(config);
	if (!result.success) {
		for (const issue of result.error.issues) errors.push({
			path: issue.path.join("."),
			message: issue.message,
			severity: "error"
		});
		return {
			valid: false,
			errors
		};
	}
	const data = result.data;
	for (const [providerName, providerConfig] of Object.entries(data.providers)) {
		if (!PROVIDER_ID_REGEX.test(providerName)) errors.push({
			path: `providers.${providerName}`,
			message: "Provider ID must start/end with alphanumeric, contain only lowercase letters, numbers, hyphens, and underscores",
			severity: "error"
		});
		if (RESERVED_PROVIDER_IDS.has(providerName) && !providerConfig.baseUrl) errors.push({
			path: `providers.${providerName}`,
			message: `Overriding built-in provider "${providerName}" requires baseUrl to be specified`,
			severity: "warning"
		});
		const hasModels = providerConfig.models && providerConfig.models.length > 0;
		const hasModelOverrides = providerConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;
		const hasBaseUrl = !!providerConfig.baseUrl;
		if (hasModels) {
			if (!hasBaseUrl) errors.push({
				path: `providers.${providerName}.baseUrl`,
				message: "baseUrl is required when defining custom models",
				severity: "error"
			});
			if (!providerConfig.apiKey) errors.push({
				path: `providers.${providerName}.apiKey`,
				message: "apiKey is required when defining custom models",
				severity: "error"
			});
		}
		if (!hasModels && !hasBaseUrl && !hasModelOverrides && !providerConfig.apiKey) errors.push({
			path: `providers.${providerName}`,
			message: "Must specify baseUrl, modelOverrides, models, or apiKey",
			severity: "error"
		});
		if (providerConfig.models) for (let i = 0; i < providerConfig.models.length; i++) {
			const model = providerConfig.models[i];
			if (!model.api && !providerConfig.api) errors.push({
				path: `providers.${providerName}.models[${i}].api`,
				message: "api is required when not specified at provider level",
				severity: "error"
			});
			if (model.id.includes("/")) errors.push({
				path: `providers.${providerName}.models[${i}].id`,
				message: "Model ID cannot contain \"/\" character",
				severity: "error"
			});
			if (model.cost) for (const field of [
				"input",
				"output",
				"cacheRead",
				"cacheWrite"
			]) {
				const value = model.cost[field];
				if (value !== void 0 && value < 0) errors.push({
					path: `providers.${providerName}.models[${i}].cost.${field}`,
					message: "Cost value cannot be negative",
					severity: "error"
				});
			}
		}
		if (providerConfig.modelOverrides) {
			for (const modelId of Object.keys(providerConfig.modelOverrides)) if (!modelId.includes("/")) errors.push({
				path: `providers.${providerName}.modelOverrides.${modelId}`,
				message: "Model override key should be in format \"provider/model-id\"",
				severity: "warning"
			});
		}
	}
	return {
		valid: errors.filter((e) => e.severity === "error").length === 0,
		errors
	};
}
function getDefaultModelValues() {
	return {
		input: ["text"],
		contextWindow: 128e3,
		maxTokens: 16384,
		cost: {
			input: 0,
			output: 0,
			cacheRead: 0,
			cacheWrite: 0
		}
	};
}
/**
* Load models.json from disk
*/
function loadModelsJson(path = resolveModelsJsonPath()) {
	if (!existsSync(path)) return { config: { providers: {} } };
	try {
		const content = readFileSync(path, "utf-8");
		const config = JSON.parse(content);
		const validation = validateModelsConfig(config);
		if (!validation.valid) return {
			config,
			error: `Validation failed: ${validation.errors.map((e) => `${e.path}: ${e.message}`).join("; ")}`
		};
		return { config };
	} catch (error) {
		return {
			config: { providers: {} },
			error: error instanceof Error ? error.message : "Failed to load models.json"
		};
	}
}
/**
* Save models.json to disk
*/
function saveModelsJson(path, config) {
	try {
		const validation = validateModelsConfig(config);
		if (!validation.valid) return {
			success: false,
			error: `Validation failed: ${validation.errors.map((e) => `${e.path}: ${e.message}`).join("; ")}`
		};
		writeTextAtomicSync(path, JSON.stringify(config, null, 2));
		return { success: true };
	} catch (error) {
		return {
			success: false,
			error: error instanceof Error ? error.message : "Failed to save models.json"
		};
	}
}
/**
* Check if models.json exists
*/
function modelsJsonExists(path = resolveModelsJsonPath()) {
	return existsSync(path);
}
var OpenRouterRoutingSchema, VercelGatewayRoutingSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenAICompatSchema, CustomModelSchema, ModelOverrideSchema, ProviderConfigSchema, ModelsJsonSchema, PROVIDER_ID_REGEX, RESERVED_PROVIDER_IDS;
var init_models_json = __esmMin((() => {
	init_write_file_atomic();
	init_paths();
	OpenRouterRoutingSchema = z.object({
		only: z.array(z.string()).optional(),
		order: z.array(z.string()).optional()
	});
	VercelGatewayRoutingSchema = z.object({
		only: z.array(z.string()).optional(),
		order: z.array(z.string()).optional()
	});
	OpenAICompletionsCompatSchema = z.object({
		supportsStore: z.boolean().optional(),
		supportsDeveloperRole: z.boolean().optional(),
		supportsReasoningEffort: z.boolean().optional(),
		supportsUsageInStreaming: z.boolean().optional(),
		maxTokensField: z.enum(["max_completion_tokens", "max_tokens"]).optional(),
		requiresToolResultName: z.boolean().optional(),
		requiresAssistantAfterToolResult: z.boolean().optional(),
		requiresThinkingAsText: z.boolean().optional(),
		requiresMistralToolIds: z.boolean().optional(),
		thinkingFormat: z.enum([
			"openai",
			"zai",
			"dashscope"
		]).optional(),
		openRouterRouting: OpenRouterRoutingSchema.optional(),
		vercelGatewayRouting: VercelGatewayRoutingSchema.optional(),
		supportsStrictMode: z.boolean().optional()
	});
	OpenAIResponsesCompatSchema = z.object({});
	OpenAICompatSchema = z.union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);
	CustomModelSchema = z.object({
		id: z.string().min(1),
		name: z.string().min(1).optional(),
		api: z.enum([
			"openai-completions",
			"openai-responses",
			"anthropic-messages",
			"google-generative-ai",
			"azure-openai-responses",
			"bedrock-converse-stream",
			"openai-codex-responses",
			"google-gemini-cli",
			"google-vertex"
		]).optional(),
		reasoning: z.boolean().optional(),
		input: z.array(z.enum(["text", "image"])).optional(),
		contextWindow: z.number().positive().optional(),
		maxTokens: z.number().positive().optional(),
		cost: z.object({
			input: z.number(),
			output: z.number(),
			cacheRead: z.number(),
			cacheWrite: z.number()
		}).optional(),
		headers: z.record(z.string(), z.string()).optional(),
		compat: OpenAICompatSchema.optional()
	});
	ModelOverrideSchema = z.object({
		name: z.string().min(1).optional(),
		reasoning: z.boolean().optional(),
		input: z.array(z.enum(["text", "image"])).optional(),
		contextWindow: z.number().positive().optional(),
		maxTokens: z.number().positive().optional(),
		cost: z.object({
			input: z.number().optional(),
			output: z.number().optional(),
			cacheRead: z.number().optional(),
			cacheWrite: z.number().optional()
		}).optional(),
		headers: z.record(z.string(), z.string()).optional(),
		compat: OpenAICompatSchema.optional()
	});
	ProviderConfigSchema = z.object({
		baseUrl: z.string().url().optional(),
		apiKey: z.string().optional(),
		api: z.enum([
			"openai-completions",
			"openai-responses",
			"anthropic-messages",
			"google-generative-ai",
			"azure-openai-responses",
			"bedrock-converse-stream",
			"openai-codex-responses",
			"google-gemini-cli",
			"google-vertex"
		]).optional(),
		headers: z.record(z.string(), z.string()).optional(),
		authHeader: z.boolean().optional(),
		models: z.array(CustomModelSchema).optional(),
		modelOverrides: z.record(z.string(), ModelOverrideSchema).optional()
	});
	ModelsJsonSchema = z.object({ providers: z.record(z.string(), ProviderConfigSchema) });
	PROVIDER_ID_REGEX = /^[a-z0-9]([a-z0-9-_]*[a-z0-9])?$/;
	RESERVED_PROVIDER_IDS = new Set([
		"amazon-bedrock",
		"anthropic",
		"azure-openai-responses",
		"cerebras",
		"cloudflare-ai-gateway",
		"cloudflare-workers-ai",
		"deepseek",
		"fireworks",
		"github-copilot",
		"google",
		"google-antigravity",
		"google-gemini-cli",
		"google-vertex",
		"groq",
		"huggingface",
		"kimi-coding",
		"minimax",
		"minimax-cn",
		"mistral",
		"moonshotai",
		"moonshotai-cn",
		"openai",
		"openai-codex",
		"opencode",
		"opencode-go",
		"openrouter",
		"together",
		"vercel-ai-gateway",
		"xai",
		"xiaomi",
		"xiaomi-token-plan-ams",
		"xiaomi-token-plan-cn",
		"xiaomi-token-plan-sgp",
		"zai"
	]);
}));
//#endregion
init_models_json();
export { CustomModelSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, resolveModelsJsonPath as getModelsJsonPath, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig };

//# sourceMappingURL=models-json.js.map