"use strict";
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isHiddenModelA = isHiddenModelA;
exports.isHiddenModelB = isHiddenModelB;
exports.isHiddenModelE = isHiddenModelE;
exports.isHiddenModelF = isHiddenModelF;
exports.isHiddenModelG = isHiddenModelG;
exports.isHiddenFamilyH = isHiddenFamilyH;
exports.isHiddenModelK = isHiddenModelK;
exports.isGpt54 = isGpt54;
exports.isGpt55 = isGpt55;
exports.isGpt55EconomicalSearchAndEditExp = isGpt55EconomicalSearchAndEditExp;
exports.isGpt55LargePromptSectionsExp = isGpt55LargePromptSectionsExp;
exports.isHiddenModelM = isHiddenModelM;
exports.isGpt53Codex = isGpt53Codex;
exports.isVSCModelA = isVSCModelA;
exports.isVSCModelB = isVSCModelB;
exports.isVSCModelReplaceStringSet = isVSCModelReplaceStringSet;
exports.isVSCModelC = isVSCModelC;
exports.isVSCModelD = isVSCModelD;
exports.isGpt52CodexFamily = isGpt52CodexFamily;
exports.isGpt52Family = isGpt52Family;
exports.modelPrefersInstructionsInUserMessage = modelPrefersInstructionsInUserMessage;
exports.modelPrefersInstructionsAfterHistory = modelPrefersInstructionsAfterHistory;
exports.modelSupportsApplyPatch = modelSupportsApplyPatch;
exports.modelPrefersJsonNotebookRepresentation = modelPrefersJsonNotebookRepresentation;
exports.modelSupportsReplaceString = modelSupportsReplaceString;
exports.modelSupportsMultiReplaceString = modelSupportsMultiReplaceString;
exports.modelCanUseReplaceStringExclusively = modelCanUseReplaceStringExclusively;
exports.modelShouldUseReplaceStringHealing = modelShouldUseReplaceStringHealing;
exports.modelCanUseMcpResultImageURL = modelCanUseMcpResultImageURL;
exports.modelCanUseImageURL = modelCanUseImageURL;
exports.modelSupportsPDFDocuments = modelSupportsPDFDocuments;
exports.modelCanUseApplyPatchExclusively = modelCanUseApplyPatchExclusively;
exports.modelNeedsStrongReplaceStringHint = modelNeedsStrongReplaceStringHint;
exports.modelSupportsSimplifiedApplyPatchInstructions = modelSupportsSimplifiedApplyPatchInstructions;
exports.isAnthropicFamily = isAnthropicFamily;
exports.isGeminiFamily = isGeminiFamily;
exports.isMinimaxFamily = isMinimaxFamily;
exports.isGpt5PlusFamily = isGpt5PlusFamily;
exports.isGptCodexFamily = isGptCodexFamily;
exports.isGpt5Family = isGpt5Family;
exports.isGptFamily = isGptFamily;
exports.isGpt51Family = isGpt51Family;
exports.getVerbosityForModelSync = getVerbosityForModelSync;
exports.modelSupportsToolSearch = modelSupportsToolSearch;
exports.modelSupportsContextEditing = modelSupportsContextEditing;
const crypto_1 = require("../../../util/common/crypto");
const configurationService_1 = require("../../configuration/common/configurationService");
const nullExperimentationService_1 = require("../../telemetry/common/nullExperimentationService");
const HIDDEN_MODEL_A_HASHES = [
    'a99dd17dfee04155d863268596b7f6dd36d0a6531cd326348dbe7416142a21a3',
    '6b0f165d0590bf8d508540a796b4fda77bf6a0a4ed4e8524d5451b1913100a95'
];
const HIDDEN_MODEL_B_HASHES = [
    '1f48b3271e760c69ab2b17dcae5f5c661fa5b644c5976a8a99b23e05ae3cb6d6',
    'ffc50c70661c227edf8daae6f8dbed2dd0645386c12d43bc7fc44da166e043bd',
    '257c934076307881132be702a901618969591f0e11e1df51b22b1d4010f0a0d0',
];
const VSC_MODEL_HASHES_A = [
    '6db59e9bfe6e2ce608c0ee0ade075c64e4d054f05305e3034481234703381bb5',
    'd7b81f23b6ab47d41130359bc203a6c653bba461b3da0185406353ce2b3abfa7',
];
const VSC_MODEL_HASHES_B = [
    '6b0f165d0590bf8d508540a796b4fda77bf6a0a4ed4e8524d5451b1913100a95',
    '1cdd4febbc7ee6b1abe0fbdd42217744c5912c79366db4befd91698b46c40a3c',
];
const VSC_MODEL_HASHES_C = [
    '0425aeda24d2fd93e2a879c4d813e4f3997aa444f1f4a633241236f9f773df73',
];
const VSC_MODEL_HASHES_D = [
    'e82ff0e2d4e4bae1f012dc599d520f8d61becfc4762f3717577b270be199db92',
];
// subset to allow replace string instead of apply patch.
const VSC_MODEL_HASHES_EDIT_TOOL_SET = [
    '6db59e9bfe6e2ce608c0ee0ade075c64e4d054f05305e3034481234703381bb5',
    '6b0f165d0590bf8d508540a796b4fda77bf6a0a4ed4e8524d5451b1913100a95',
    'd7b81f23b6ab47d41130359bc203a6c653bba461b3da0185406353ce2b3abfa7',
    '1cdd4febbc7ee6b1abe0fbdd42217744c5912c79366db4befd91698b46c40a3c',
    '0425aeda24d2fd93e2a879c4d813e4f3997aa444f1f4a633241236f9f773df73',
    'e82ff0e2d4e4bae1f012dc599d520f8d61becfc4762f3717577b270be199db92',
];
const HIDDEN_MODEL_E_HASHES = [
    '6013de0381f648b7f21518885c02b40b7583adfb33c6d9b64d3aed52c3934798'
];
const HIDDEN_MODEL_F_HASHES = [
    'ab45e8474269b026f668d49860b36850122e18a50d5ea38f3fefdae08261865c',
    '9542d5c077c2bc379f92be32272b14be8b94a8841323465db0d5b3d6f4f0dab0',
];
const HIDDEN_MODEL_J_HASHES = [
    '0a4346f806b28b3ce94905c3ac56fcd5ee2337d8613161696aba52eb0c3551cc',
    '2a7b79b0151aa44a0abee17adc0e18df1c07d8d15d7affa989c3b3afb6bee0a0',
    'f3c2984127dd2db50a555194925ca0d55c3c7b676e889c9406b2e6875a67e29c',
    '5a81e6aa7556585ba7c569881d1103683adc9e0124ff7952df423afba2f167b5',
];
const HIDDEN_MODEL_K_HASH = 'a62e299160a1075d9973c28a7aa77f446c21c09887c7aa65c11022918cf83eda';
const HIDDEN_FAMILY_H_HASHES = [
    '70fcded3f255d368e868cc807d8838a62108bfa5c86ce7d37966f58cda229e33',
];
const HIDDEN_FAMILY_M_HASHES = [
    '0902565c0c0fe145633a1f246ae551acc0f621249ef050428eba357fbd4655ee',
];
function getModelId(model) {
    return 'id' in model ? model.id : model.model;
}
function isHiddenModelA(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(model.family);
    return HIDDEN_MODEL_A_HASHES.includes(h);
}
function isHiddenModelB(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(typeof model === 'string' ? model : model.family);
    return HIDDEN_MODEL_B_HASHES.includes(h);
}
function isHiddenModelE(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(model.family);
    return HIDDEN_MODEL_E_HASHES.includes(h);
}
function isHiddenModelF(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(model.family);
    return HIDDEN_MODEL_F_HASHES.includes(h);
}
function isHiddenModelG(model) {
    const family_hash = (0, crypto_1.getCachedSha256Hash)(typeof model === 'string' ? model : model.family);
    return family_hash === '3ae755cc6122a54cc873e3ba2bd8703883b4a711d1af2707ef00f2c2c963ee8d';
}
function isHiddenFamilyH(model) {
    const family_hash = (0, crypto_1.getCachedSha256Hash)(model.family);
    return HIDDEN_FAMILY_H_HASHES.includes(family_hash);
}
function isHiddenModelK(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(model.family);
    return h === HIDDEN_MODEL_K_HASH;
}
function isGpt54(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(typeof model === 'string' ? model : model.family);
    const family = typeof model === 'string' ? model : model.family;
    return family.startsWith('gpt-5.4') || HIDDEN_MODEL_J_HASHES.includes(h);
}
function isGpt55(model) {
    const h = (0, crypto_1.getCachedSha256Hash)(typeof model === 'string' ? model : model.family);
    const family = typeof model === 'string' ? model : model.family;
    return family.startsWith('gpt-5.5') || HIDDEN_MODEL_B_HASHES.includes(h);
}
function isGpt55EconomicalSearchAndEditExp(accessor, model) {
    const configurationService = accessor.get(configurationService_1.IConfigurationService);
    const experimentationService = accessor.get(nullExperimentationService_1.IExperimentationService);
    return isGpt55(model) && configurationService.getExperimentBasedConfig(configurationService_1.ConfigKey.EnableGpt55EconomicalSearchAndEdit, experimentationService);
}
function isGpt55LargePromptSectionsExp(accessor, model) {
    const configurationService = accessor.get(configurationService_1.IConfigurationService);
    const experimentationService = accessor.get(nullExperimentationService_1.IExperimentationService);
    return isGpt55(model) && configurationService.getExperimentBasedConfig(configurationService_1.ConfigKey.EnableGpt55LargePromptSections, experimentationService);
}
function isHiddenModelM(model) {
    const family_hash = (0, crypto_1.getCachedSha256Hash)(typeof model === 'string' ? model : model.family);
    return HIDDEN_FAMILY_M_HASHES.includes(family_hash);
}
function isGpt53Codex(model) {
    const family = typeof model === 'string' ? model : model.family;
    return family.startsWith('gpt-5.3-codex');
}
function isVSCModelA(model) {
    const ID_hash = (0, crypto_1.getCachedSha256Hash)(getModelId(model));
    const family_hash = (0, crypto_1.getCachedSha256Hash)(model.family);
    return VSC_MODEL_HASHES_A.includes(ID_hash) || VSC_MODEL_HASHES_A.includes(family_hash);
}
function isVSCModelB(model) {
    const ID_hash = (0, crypto_1.getCachedSha256Hash)(getModelId(model));
    const family_hash = (0, crypto_1.getCachedSha256Hash)(model.family);
    return VSC_MODEL_HASHES_B.includes(ID_hash) || VSC_MODEL_HASHES_B.includes(family_hash);
}
function isVSCModelReplaceStringSet(model) {
    const ID_hash = (0, crypto_1.getCachedSha256Hash)(getModelId(model));
    const family_hash = (0, crypto_1.getCachedSha256Hash)(model.family);
    return VSC_MODEL_HASHES_EDIT_TOOL_SET.includes(ID_hash) || VSC_MODEL_HASHES_EDIT_TOOL_SET.includes(family_hash);
}
function isVSCModelC(model) {
    const ID_hash = (0, crypto_1.getCachedSha256Hash)(getModelId(model));
    const family_hash = (0, crypto_1.getCachedSha256Hash)(model.family);
    return VSC_MODEL_HASHES_C.includes(ID_hash) || VSC_MODEL_HASHES_C.includes(family_hash);
}
function isVSCModelD(model) {
    const ID_hash = (0, crypto_1.getCachedSha256Hash)(getModelId(model));
    const family_hash = (0, crypto_1.getCachedSha256Hash)(model.family);
    return VSC_MODEL_HASHES_D.includes(ID_hash) || VSC_MODEL_HASHES_D.includes(family_hash);
}
function isGpt52CodexFamily(model) {
    const family = typeof model === 'string' ? model : model.family;
    return family === 'gpt-5.2-codex';
}
function isGpt52Family(model) {
    const family = typeof model === 'string' ? model : model.family;
    return family === 'gpt-5.2';
}
/**
 * Returns whether the instructions should be given in a user message instead
 * of a system message when talking to the model.
 */
function modelPrefersInstructionsInUserMessage(modelFamily) {
    return modelFamily.includes('claude-3.5-sonnet');
}
/**
 * Returns whether the instructions should be presented after the history
 * for the given model.
 */
function modelPrefersInstructionsAfterHistory(modelFamily) {
    return modelFamily.includes('claude-3.5-sonnet');
}
/**
 * Model supports apply_patch as an edit tool.
 */
function modelSupportsApplyPatch(model) {
    // only using replace string as edit tool, disable apply_patch for VSC Models
    if (isVSCModelReplaceStringSet(model)) {
        return false;
    }
    return (model.family.startsWith('gpt') && !model.family.includes('gpt-4o'))
        || model.family === 'o4-mini'
        || isGpt52CodexFamily(model.family)
        || isGpt53Codex(model.family)
        || isVSCModelA(model)
        || isVSCModelB(model)
        || isGpt52Family(model.family)
        || isGpt54(model)
        || isHiddenModelB(model)
        || isHiddenModelM(model);
}
/**
 * Model prefers JSON notebook representation.
 */
function modelPrefersJsonNotebookRepresentation(model) {
    return (model.family.startsWith('gpt') && !model.family.includes('gpt-4o'))
        || model.family === 'o4-mini'
        || isGpt52CodexFamily(model.family)
        || isGpt53Codex(model.family)
        || isGpt52Family(model.family)
        || isGpt54(model)
        || isHiddenModelB(model)
        || isHiddenModelM(model);
}
/**
 * Model supports replace_string_in_file as an edit tool.
 */
function modelSupportsReplaceString(model) {
    return isGeminiFamily(model) || model.family.includes('grok-code') || modelSupportsMultiReplaceString(model) || isHiddenModelF(model) || isMinimaxFamily(model) || isHiddenFamilyH(model);
}
/**
 * Model supports multi_replace_string_in_file as an edit tool.
 */
function modelSupportsMultiReplaceString(model) {
    return isAnthropicFamily(model) || isHiddenModelE(model) || isVSCModelReplaceStringSet(model) || isMinimaxFamily(model) || isHiddenFamilyH(model);
}
/**
 * The model is capable of using replace_string_in_file exclusively,
 * without needing insert_edit_into_file.
 */
function modelCanUseReplaceStringExclusively(model) {
    return isAnthropicFamily(model) || model.family.includes('grok-code') || isHiddenModelE(model) || model.family.toLowerCase().includes('gemini-3') || isVSCModelReplaceStringSet(model) || isHiddenModelF(model) || isMinimaxFamily(model) || isHiddenFamilyH(model);
}
/**
 * We should attempt to automatically heal incorrect edits the model may emit.
 * @note whether this is respected is currently controlled via EXP
 */
function modelShouldUseReplaceStringHealing(model) {
    return model.family.includes('gemini-2');
}
/**
 * The model can accept image urls as the `image_url` parameter in mcp tool results.
 */
function modelCanUseMcpResultImageURL(model) {
    return !isAnthropicFamily(model) && !isHiddenModelE(model);
}
/**
 * The model can accept image urls as the `image_url` parameter in requests.
 */
function modelCanUseImageURL(model) {
    return true;
}
/**
 * The model supports native PDF document processing via document content parts.
 */
function modelSupportsPDFDocuments(model) {
    return isAnthropicFamily(model);
}
/**
 * The model is capable of using apply_patch as an edit tool exclusively,
 * without needing insert_edit_into_file.
 */
function modelCanUseApplyPatchExclusively(model) {
    // only using replace string as edit tool, disable apply_patch for VSC Models
    if (isVSCModelReplaceStringSet(model)) {
        return false;
    }
    return isGpt5PlusFamily(model) || isVSCModelA(model) || isVSCModelB(model);
}
/**
 * Whether, when replace_string and insert_edit tools are both available,
 * verbiage should be added in the system prompt directing the model to prefer
 * replace_string.
 */
function modelNeedsStrongReplaceStringHint(model) {
    return isGeminiFamily(model) || isHiddenModelF(model);
}
/**
 * Model can take the simple, modern apply_patch instructions.
 */
function modelSupportsSimplifiedApplyPatchInstructions(model) {
    return isGpt5PlusFamily(model) || isVSCModelA(model) || isVSCModelB(model);
}
function isAnthropicFamily(model) {
    return model.family.startsWith('claude') || model.family.startsWith('Anthropic') || isHiddenModelG(model);
}
function isGeminiFamily(model) {
    const family = typeof model === 'string' ? model : model.family;
    return family.toLowerCase().startsWith('gemini') || (0, crypto_1.getCachedSha256Hash)(family) === HIDDEN_MODEL_K_HASH;
}
function isMinimaxFamily(model) {
    return model.family.toLowerCase().includes('minimax');
}
function isGpt5PlusFamily(model) {
    if (!model) {
        return false;
    }
    const family = typeof model === 'string' ? model : model.family;
    return !!family.startsWith('gpt-5');
}
/**
 * Matches gpt-5-codex, gpt-5.1-codex, gpt-5.1-codex-mini, and any future models in this general family
 */
function isGptCodexFamily(model) {
    if (!model) {
        return false;
    }
    const family = typeof model === 'string' ? model : model.family;
    return (!!family.startsWith('gpt-') && family.includes('-codex'));
}
/**
 * GPT-5, -mini, -codex, not 5.1+
 */
function isGpt5Family(model) {
    if (!model) {
        return false;
    }
    const family = typeof model === 'string' ? model : model.family;
    return family === 'gpt-5' || family === 'gpt-5-mini' || family === 'gpt-5-codex';
}
function isGptFamily(model) {
    if (!model) {
        return false;
    }
    const family = typeof model === 'string' ? model : model.family;
    return !!family.startsWith('gpt-');
}
/**
 * Any GPT-5.1+ model
 */
function isGpt51Family(model) {
    if (!model) {
        return false;
    }
    const family = typeof model === 'string' ? model : model.family;
    return !!family.startsWith('gpt-5.1');
}
/**
 * This takes a sync shortcut and should only be called when a model hash would have already been computed while rendering the prompt.
 */
function getVerbosityForModelSync(model) {
    if (model.family === 'gpt-5.1' || model.family === 'gpt-5-mini') {
        return 'low';
    }
    return undefined;
}
/**
 * Tool search is supported by:
 * - Claude Sonnet 4.5 (claude-sonnet-4-5-* or claude-sonnet-4.5-*)
 * - Claude Sonnet 4.6 (claude-sonnet-4-6-* or claude-sonnet-4.6-*)
 * - Claude Opus 4.5 (claude-opus-4-5-* or claude-opus-4.5-*)
 * - Claude Opus 4.6 (claude-opus-4-6-* or claude-opus-4.6-*)
 * - Claude Opus 4.7 (claude-opus-4-7-* or claude-opus-4.7-*)
 * - OpenAI gpt-5.4 and gpt-5.5 (via Responses API client-side tool search)
 */
function modelSupportsToolSearch(modelId) {
    const normalized = modelId.toLowerCase().replace(/\./g, '-');
    return normalized === 'gpt-5-4' ||
        normalized === 'gpt-5-5' ||
        normalized.startsWith('claude-sonnet-4-5') ||
        normalized.startsWith('claude-sonnet-4-6') ||
        normalized.startsWith('claude-opus-4-5') ||
        normalized.startsWith('claude-opus-4-6') ||
        normalized.startsWith('claude-opus-4-7') ||
        isHiddenModelG(modelId) || isHiddenModelM(modelId);
}
/**
 * Context editing is supported by:
 * - Claude Haiku 4.5 (claude-haiku-4-5-* or claude-haiku-4.5-*)
 * - Claude Sonnet 4.6 (claude-sonnet-4-6-* or claude-sonnet-4.6-*)
 * - Claude Sonnet 4.5 (claude-sonnet-4-5-* or claude-sonnet-4.5-*)
 * - Claude Sonnet 4 (claude-sonnet-4-*)
 * - Claude Opus 4.6 (claude-opus-4-6-* or claude-opus-4.6-*)
 * - Claude Opus 4.5 (claude-opus-4-5-* or claude-opus-4.5-*)
 * - Claude Opus 4.1 (claude-opus-4-1-* or claude-opus-4.1-*)
 * - Claude Opus 4 (claude-opus-4-*)
 * Provider-agnostic: add additional model prefixes here as other providers adopt context editing.
 */
function modelSupportsContextEditing(modelId) {
    const normalized = modelId.toLowerCase().replace(/\./g, '-');
    // The 1M context variant doesn't need context editing
    if (normalized.includes('1m')) {
        return false;
    }
    return normalized.startsWith('claude-haiku-4-5') ||
        normalized.startsWith('claude-sonnet-4-6') ||
        normalized.startsWith('claude-sonnet-4-5') ||
        normalized.startsWith('claude-sonnet-4') ||
        normalized.startsWith('claude-opus-4-6') ||
        normalized.startsWith('claude-opus-4-5') ||
        normalized.startsWith('claude-opus-4-1') ||
        normalized.startsWith('claude-opus-4');
}
//# sourceMappingURL=chatModelCapabilities.js.map