hi we recently completed a refactor to support a new ML model for our following code please review it then i will provide you the test error:

```
# confidence_scorer.py

from typing import Dict, Any, Tuple, List, Set
from rapidfuzz import fuzz
from nltk.corpus import wordnet
import nltk
import re
import logging
from functools import lru_cache
import json
import numpy as np # Import Numpy for array handling
import warnings
import torch  # Import torch for device checking

# Ensure NLTK WordNet data is downloaded
try:
    nltk.data.find('corpora/wordnet')
except LookupError:
    nltk.download('wordnet', quiet=True)

# ----------------- Constants -----------------

# Confidence thresholds
HIGH_CONFIDENCE_THRESHOLD: float = 0.75 # Increased from 0.7
MEDIUM_CONFIDENCE_THRESHOLD: float = 0.6 # Increased from 0.55
LOW_CONFIDENCE_THRESHOLD: float = 0.35 # Increased from 0.3

# Relevant keywords for scope determination
RELEVANT_KEYWORDS: Set[str] = {
'import', 'comment', 'print', 'file', 'global',
'function', 'class', 'method', 'update', 'modify',
'change', 'compute', 'calculate'
}

# Synonym mapping using WordNet

def initialize_synonym_map() -> Dict[str, Set[str]]:
    """
    Initializes a synonym map for relevant keywords using WordNet.

    Returns:
    Dict[str, Set[str]]: A dictionary mapping each keyword to a set of its synonyms.
    """
    synonym_map: Dict[str, Set[str]] = {}
    for keyword in RELEVANT_KEYWORDS:
        synonyms = {lemma.name().lower().replace('', ' ') for syn in wordnet.synsets(keyword) for lemma in syn.lemmas()}
        synonym_map[keyword] = synonyms
    return synonym_map

SYNONYM_MAP = initialize_synonym_map()

# ----------------- Logging Configuration -----------------

logging.basicConfig(
    level=logging.DEBUG,  # Adjust as needed (DEBUG, INFO, WARNING, etc.)
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


# ----------------- Helper Function for Device Selection -----------------

def get_available_device() -> str:
    """
    Detects the available device for PyTorch operations.

    Returns:
        str: The device name ('cuda', 'mps', or 'cpu').
    """
    if torch.cuda.is_available():
        return 'cuda'
    elif torch.backends.mps.is_available() and torch.backends.mps.is_built():
        return 'mps'
    else:
        return 'cpu'

# ----------------- ConfidenceScorer Class -------------------

class ConfidenceScorer:
    """
    Base class for calculating confidence scores for code edit operations.

    Attributes:
        efc (Dict[str, Any]): Enhanced File Context containing code structure.
        query (str): The edit instruction or query.
        model (SentenceTransformer): Pre-trained model for generating embeddings.
        query_embedding (np.ndarray): Embedding vector for the query.
    """

    def __init__(self, efc: Dict[str, Any], query: str, model_name: str = 'Alibaba-NLP/gte-base-en-v1.5', device: str = None):
        """
        Initializes the ConfidenceScorer with the provided Enhanced File Context and query.

        Args:
            efc (Dict[str, Any]): Enhanced File Context.
            query (str): The edit instruction or query.
            model_name (str, optional): Pre-trained model name. Defaults to 'Alibaba-NLP/gte-base-en-v1.5'.
            device (str, optional): Device to run the model on. 'cuda', 'mps', or 'cpu'. If None, auto-detect.
        """
        self.efc: Dict[str, Any] = efc
        self.query: str = query
        self.device: str = device if device else get_available_device()
        self.model = self._initialize_model(model_name).to(self.device)
        self.query_embedding: np.ndarray = self.get_embedding(self.query, prompt_name="s2s_query")

    @staticmethod
    def _initialize_model(model_name: str):
        """
        Initializes the SentenceTransformer model.

        Args:
            model_name (str): Name of the pre-trained model.

        Returns:
            SentenceTransformer: The initialized model.
        """
        try:
            from sentence_transformers import SentenceTransformer
            return SentenceTransformer(model_name, trust_remote_code=True)
        except ImportError:
            logger.error("Please install 'sentence-transformers' package.")
            raise

    @lru_cache(maxsize=128)
    def get_embedding(self, text: str, prompt_name: str = "s2s_query") -> np.ndarray:
        """
        Generates an embedding for the given text using the pre-trained model.

        Args:
            text (str): Text to be embedded.
            prompt_name (str, optional): Prompt type ('s2p_query' or 's2s_query'). Defaults to "s2s_query".

        Returns:
            np.ndarray: The embedding vector.
        """
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", FutureWarning)
            embedding = self.model.encode(
                text, 
                prompt_name=prompt_name, 
                convert_to_tensor=False, 
                max_length=8192,    # Set according to model's capability
                truncation=True     # Truncate if exceeding max_length
            )
            logger.debug(f"Generated embedding for text: '{text}' with shape: {embedding.shape}")
            return embedding

    def calculate_confidence(self) -> float:
        """
        Calculates the overall confidence score based on semantic similarity.

        Returns:
            float: Confidence score normalized between 0 and 1.
        """
        code_block_names = [block['name'] for block in self.efc.get('custom_tokens', [])]
        code_block_contents = [block['code'] for block in self.efc.get('custom_tokens', [])]

        name_embeddings = [self.get_embedding(name, prompt_name="s2s_query") for name in code_block_names]
        content_embeddings = [self.get_embedding(content, prompt_name="s2s_query") for content in code_block_contents]

        best_name_score = self._get_best_similarity(self.query_embedding, name_embeddings)
        best_content_score = self._get_best_similarity(self.query_embedding, content_embeddings)

        # Weighted confidence: name and content contribute equally
        confidence = (0.5 * best_name_score) + (0.5 * best_content_score)
        logger.debug(f"Calculated confidence - Name: {best_name_score}, Content: {best_content_score}, Combined: {confidence}")
        return confidence

    @staticmethod
    def _get_best_similarity(query_embedding: np.ndarray, embeddings: List[np.ndarray]) -> float:
        """
        Computes the highest cosine similarity score between the query embedding and a list of embeddings.

        Args:
            query_embedding (np.ndarray): Embedding vector for the query.
            embeddings (List[np.ndarray]): List of embedding vectors to compare against.

        Returns:
            float: The highest similarity score between 0 and 1.
        """
        if not embeddings:
            return 0.0
        # Vectorized similarity computation
        stacked_embeddings = np.vstack(embeddings)  # Shape: (num_embeddings, 768)
        norm_query = np.linalg.norm(query_embedding)
        norm_embeddings = np.linalg.norm(stacked_embeddings, axis=1, keepdims=True)
        if norm_query == 0 or np.any(norm_embeddings == 0):
            return 0.0
        normalized_query = query_embedding / norm_query
        normalized_embeddings = stacked_embeddings / norm_embeddings
        similarities = np.dot(normalized_embeddings, normalized_query)
        best_similarity = np.max(similarities)
        logger.debug(f"Computed best similarity: {best_similarity}")
        return best_similarity

    @staticmethod
    def _cosine_similarity(vec1: np.ndarray, vec2: np.ndarray) -> float:
        """
        Computes the cosine similarity between two vectors.

        Args:
            vec1 (np.ndarray): First vector.
            vec2 (np.ndarray): Second vector.

        Returns:
            float: Cosine similarity between 0 and 1.
        """
        if vec1.size == 0 or vec2.size == 0:
            return 0.0
        dot_product = np.dot(vec1, vec2)
        magnitude1 = np.linalg.norm(vec1)
        magnitude2 = np.linalg.norm(vec2)
        if magnitude1 == 0 or magnitude2 == 0:
            return 0.0
        return dot_product / (magnitude1 * magnitude2)

    def assess_complexity(self) -> float:
        """
        Assesses the complexity of the edit based on the length and keyword richness of the query.

        Returns:
            float: Complexity score normalized between 0 and 1.
        """
        query_length = len(self.query.split())
        keyword_count = len(set(self.query.lower().split()).intersection(RELEVANT_KEYWORDS))
        complexity = (query_length / 20) + (keyword_count / len(RELEVANT_KEYWORDS))
        normalized_complexity = min(complexity / 2, 1.0)  # Normalize to 0-1
        logger.debug(f"Assessed complexity: {normalized_complexity} (length: {query_length}, keywords: {keyword_count})")
        return normalized_complexity

    def determine_scope(self) -> Tuple[str, float]:
        """
        Determines the appropriate scope for the edit operation based on confidence and complexity.

        Returns:
            Tuple[str, float]: The determined scope and confidence score.
        """
        confidence: float = self.calculate_confidence()
        complexity: float = self.assess_complexity()

        has_relevant_keyword: bool = self._has_relevant_keyword()

        if not has_relevant_keyword:
            scope = "file-level edit"
        else:
            # Prioritize function scope if function keywords are present
            function_keywords = {'function', 'def', 'method', 'update', 'modify', 'change', 'compute', 'calculate'}
            query_words = set(re.findall(r'\w+', self.query.lower()))
            is_function_related = bool(query_words.intersection(function_keywords))

            if is_function_related and confidence > HIGH_CONFIDENCE_THRESHOLD and complexity < 0.3:
                scope = "function"
            elif confidence > MEDIUM_CONFIDENCE_THRESHOLD and complexity < 0.6:
                scope = "class"
            else:
                scope = "file-level edit"

        logger.debug(f"Determine Scope - Confidence: {confidence}, Complexity: {complexity}, Scope: {scope}")
        return scope, confidence

    def _has_relevant_keyword(self) -> bool:
        """
        Checks if the query contains any relevant keywords or their synonyms.

        Returns:
            bool: True if relevant keywords are present, False otherwise.
        """
        query_words = set(re.findall(r'\w+', self.query.lower()))
        for keyword, synonyms in SYNONYM_MAP.items():
            if query_words.intersection(synonyms.union({keyword})):
                logger.debug(f"Relevant keyword detected: {keyword}")
                return True
        return False

# ----------------- EnhancedConfidenceScorer Class -----------------

class EnhancedConfidenceScorer(ConfidenceScorer):
    """
    Advanced confidence scoring system for code edit operations.

    Extends ConfidenceScorer with multi-dimensional confidence scoring and enhanced keyword recognition.
    """

    def __init__(self, efc: Dict[str, Any], query: str, model_name: str = 'Alibaba-NLP/gte-base-en-v1.5', device: str = None):
        super().__init__(efc, query, model_name, device)

    def calculate_confidence(self) -> Dict[str, float]:
        """
        Calculates multi-dimensional confidence scores:
        - overall: Combined confidence score
        - name: Confidence in identifying the correct code block
        - content: Confidence in understanding the required changes
        - context: Confidence in the surrounding code context

        Returns:
            Dict[str, float]: Dictionary containing confidence scores.
        """
        name_similarity = self._calculate_name_confidence()
        content_similarity = self._calculate_content_confidence()
        context_confidence = self._calculate_context_confidence()

        # Weighting factors
        NAME_WEIGHT: float = 0.35
        CONTENT_WEIGHT: float = 0.5
        CONTEXT_WEIGHT: float = 0.15

        base_confidence: float = (
            name_similarity * NAME_WEIGHT +
            content_similarity * CONTENT_WEIGHT +
            context_confidence * CONTEXT_WEIGHT
        )

        # Apply boosting based on operation type
        boosted_confidence: float = self._boost_confidence(base_confidence)

        # Apply graceful degradation for low confidence
        confidence_scores: Dict[str, float] = {
            "overall": round(float(boosted_confidence), 2),
            "name": round(float(name_similarity), 2),
            "content": round(float(content_similarity), 2),
            "context": round(float(context_confidence), 2)
        }
        confidence_scores = self._apply_graceful_degradation(confidence_scores)

        logger.debug(f"Calculated confidence scores: {json.dumps(confidence_scores, indent=2)}")
        return confidence_scores

    def determine_scope(self) -> Tuple[str, Dict[str, float]]:
        """
        Determines the edit scope based on multi-dimensional confidence scores.

        Returns:
            Tuple[str, Dict[str, float]]: The determined scope and confidence scores.
        """
        confidence_scores: Dict[str, float] = self.calculate_confidence()
        complexity: float = self.assess_complexity()

        logger.debug(f"Instruction: {self.query}")
        logger.debug(f"Confidence scores: {confidence_scores}")
        logger.debug(f"Complexity: {complexity}")

        if not self.query.strip():
            confidence_scores = {
                "overall": 0.0,
                "name": 0.0,
                "content": 0.0,
                "context": 0.5  # Retain default context confidence
            }
            logger.debug("Empty query detected. Defaulting to 'file-level edit' with zero confidence.")
            return "file-level edit", confidence_scores

        if self._is_file_level_operation():
            logger.debug("Scope determined: File-level edit (file-level operation detected)")
            return "file-level edit", confidence_scores

        # Prioritize class-level operations first
        if self._is_class_level_operation():
            if (confidence_scores['overall'] > 0.6 and 
                confidence_scores['content'] > 0.6 and 
                complexity < 0.6):
                scope = "class"
            else:
                scope = "file-level edit"
            logger.debug(f"Scope determined: {scope} (Class-level operation)")
            return scope, confidence_scores

        # Then check for function-level operations
        if self._is_function_level_operation():
            if (confidence_scores['overall'] > 0.7 and 
                confidence_scores['content'] > 0.7 and 
                complexity < 0.3):
                scope = "function"
            else:
                scope = "file-level edit"
            logger.debug(f"Scope determined: {scope} (Function-level operation)")
            return scope, confidence_scores

        # Existing logic for file-level or ambiguous scopes
        if not self._has_relevant_keyword():
            scope = "file-level edit"
            logger.debug("Scope determined: File-level edit (irrelevant or vague instruction)")
        elif confidence_scores['overall'] > HIGH_CONFIDENCE_THRESHOLD:
            scope = "function"
            logger.debug("Scope determined: Function (high confidence)")
        elif confidence_scores['overall'] > MEDIUM_CONFIDENCE_THRESHOLD:
            scope = "class"
            logger.debug("Scope determined: Class (medium confidence)")
        else:
            scope = "file-level edit"
            logger.debug("Scope determined: File-level edit (default case)")
        return scope, confidence_scores

    def _calculate_name_confidence(self) -> float:
        """
        Calculates confidence in identifying the correct code block based on names.

        Returns:
            float: Name confidence score between 0 and 1.
        """
        code_block_names = [block['name'] for block in self.efc.get('custom_tokens', [])]
        name_similarity = self._get_best_similarity(
            self.query_embedding, 
            [self.get_embedding(name, prompt_name="s2s_query") for name in code_block_names]
        )
        logger.debug(f"Name similarity score: {name_similarity}")
        return name_similarity

    def _calculate_content_confidence(self) -> float:
        """
        Calculates confidence in understanding the required changes based on code content.

        Returns:
            float: Content confidence score between 0 and 1.
        """
        code_block_contents = [block['code'] for block in self.efc.get('custom_tokens', [])]
        content_similarity = self._get_best_similarity(
            self.query_embedding, 
            [self.get_embedding(content, prompt_name="s2s_query") for content in code_block_contents]
        )
        logger.debug(f"Content similarity score: {content_similarity}")
        return content_similarity

    def _calculate_context_confidence(self) -> float:
        """
        Calculates confidence in the surrounding code context.

        Returns:
            float: Context confidence score between 0 and 1.
        """
        # Example: Higher confidence if the query mentions keywords related to context
        contextual_keywords: Set[str] = {'syntax', 'structure', 'format', 'refactor'}
        query_tags = set(re.findall(r'\w+', self.query.lower()))
        common_keywords = query_tags.intersection(contextual_keywords)
        context_confidence = 1.0 if common_keywords else 0.5
        logger.debug(f"Context confidence score: {context_confidence}")
        return context_confidence

    def _boost_confidence(self, base_confidence: float) -> float:
        """
        Boosts the confidence score based on the type of operation detected.

        Args:
            base_confidence (float): The initial confidence score.

        Returns:
            float: The boosted confidence score, capped at 0.95.
        """
        if self._is_file_level_operation():
            boosted = min(base_confidence * 1.2, 0.95)
            logger.debug(f"Boosted confidence for file-level operation: {boosted}")
            return boosted
        elif self._is_function_level_operation():
            boosted = min(base_confidence * 1.2, 0.95)  # Increased boost multiplier
            logger.debug(f"Boosted confidence for function-level operation: {boosted}")
            return boosted
        return base_confidence

    def _apply_graceful_degradation(self, confidence_scores: Dict[str, float]) -> Dict[str, float]:
        """
        Applies graceful degradation to confidence scores if overall confidence is low.

        Args:
            confidence_scores (Dict[str, float]): The current confidence scores.

        Returns:
            Dict[str, float]: The adjusted confidence scores.
        """
        if confidence_scores['overall'] < LOW_CONFIDENCE_THRESHOLD:
            degraded_scores = {
                k: min(v * 0.8, 0.4) if k != 'context' else 0.5
                for k, v in confidence_scores.items()
            }
            logger.debug(f"Applied graceful degradation: {degraded_scores}")
            return degraded_scores
        return confidence_scores

    def _is_file_level_operation(self) -> bool:
        """
        Determines if the operation is at the file level based on keywords.

        Returns:
            bool: True if file-level operation, False otherwise.
        """
        file_level_keywords = {'import', 'comment', 'print', 'file', 'global'}
        query_words = set(re.findall(r'\w+', self.query.lower()))
        is_file_level = bool(query_words.intersection(file_level_keywords))
        logger.debug(f"Is file-level operation: {is_file_level}")
        return is_file_level

    def _is_function_level_operation(self) -> bool:
        """
        Determines if the operation is at the function level based on keywords.

        Returns:
            bool: True if function-level operation, False otherwise.
        """
        function_keywords = {'function', 'def', 'method', 'update', 'modify'}
        query_words = set(re.findall(r'\w+', self.query.lower()))
        is_function_level = bool(query_words.intersection(function_keywords))
        logger.debug(f"Is function-level operation: {is_function_level}")
        return is_function_level

    def _is_class_level_operation(self) -> bool:
        """
        Determines if the operation is at the class level based on keywords.

        Returns:
            bool: True if class-level operation, False otherwise.
        """
        class_keywords = {'class'}
        query_words = set(re.findall(r'\w+', self.query.lower()))
        is_class_level = bool(query_words.intersection(class_keywords))
        logger.debug(f"Is class-level operation: {is_class_level}")
        return is_class_level
```


```
gte-base-en-v1.5
We introduce gte-v1.5 series, upgraded gte embeddings that support the context length of up to 8192, while further enhancing model performance. The models are built upon the transformer++ encoder backbone (BERT + RoPE + GLU).

The gte-v1.5 series achieve state-of-the-art scores on the MTEB benchmark within the same model size category and prodvide competitive on the LoCo long-context retrieval tests (refer to Evaluation).

We also present the gte-Qwen1.5-7B-instruct, a SOTA instruction-tuned multi-lingual embedding model that ranked 2nd in MTEB and 1st in C-MTEB.

Developed by: Institute for Intelligent Computing, Alibaba Group
Model type: Text Embeddings
Paper: mGTE: Generalized Long-Context Text Representation and Reranking Models for Multilingual Text Retrieval
Model list
Models	Language	Model Size	Max Seq. Length	Dimension	MTEB-en	LoCo
gte-Qwen1.5-7B-instruct	Multiple	7720	32768	4096	67.34	87.57
gte-large-en-v1.5	English	434	8192	1024	65.39	86.71
gte-base-en-v1.5	English	137	8192	768	64.11	87.44
How to Get Started with the Model
Use the code below to get started with the model.

# Requires transformers>=4.36.0

import torch.nn.functional as F
from transformers import AutoModel, AutoTokenizer

input_texts = [
    "what is the capital of China?",
    "how to implement quick sort in python?",
    "Beijing",
    "sorting algorithms"
]

model_path = 'Alibaba-NLP/gte-base-en-v1.5'
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModel.from_pretrained(model_path, trust_remote_code=True)

# Tokenize the input texts
batch_dict = tokenizer(input_texts, max_length=8192, padding=True, truncation=True, return_tensors='pt')

outputs = model(**batch_dict)
embeddings = outputs.last_hidden_state[:, 0]
 
# (Optionally) normalize embeddings
embeddings = F.normalize(embeddings, p=2, dim=1)
scores = (embeddings[:1] @ embeddings[1:].T) * 100
print(scores.tolist())

It is recommended to install xformers and enable unpadding for acceleration, refer to enable-unpadding-and-xformers.

Use with sentence-transformers:

# Requires sentence_transformers>=2.7.0

from sentence_transformers import SentenceTransformer
from sentence_transformers.util import cos_sim

sentences = ['That is a happy person', 'That is a very happy person']

model = SentenceTransformer('Alibaba-NLP/gte-base-en-v1.5', trust_remote_code=True)
embeddings = model.encode(sentences)
print(cos_sim(embeddings[0], embeddings[1]))

Use with transformers.js:

// npm i @xenova/transformers
import { pipeline, dot } from '@xenova/transformers';

// Create feature extraction pipeline
const extractor = await pipeline('feature-extraction', 'Alibaba-NLP/gte-base-en-v1.5', {
    quantized: false, // Comment out this line to use the quantized version
});

// Generate sentence embeddings
const sentences = [
    "what is the capital of China?",
    "how to implement quick sort in python?",
    "Beijing",
    "sorting algorithms"
]
const output = await extractor(sentences, { normalize: true, pooling: 'cls' });

// Compute similarity scores
const [source_embeddings, ...document_embeddings ] = output.tolist();
const similarities = document_embeddings.map(x => 100 * dot(source_embeddings, x));
console.log(similarities); // [34.504930869007296, 64.03973265120138, 19.520042686034362]

Training Details
Training Data
Masked language modeling (MLM): c4-en
Weak-supervised contrastive pre-training (CPT): GTE pre-training data
Supervised contrastive fine-tuning: GTE fine-tuning data
Training Procedure
To enable the backbone model to support a context length of 8192, we adopted a multi-stage training strategy. The model first undergoes preliminary MLM pre-training on shorter lengths. And then, we resample the data, reducing the proportion of short texts, and continue the MLM pre-training.

The entire training process is as follows:

MLM-2048: lr 5e-4, mlm_probability 0.3, batch_size 4096, num_steps 70000, rope_base 10000
MLM-8192: lr 5e-5, mlm_probability 0.3, batch_size 1024, num_steps 20000, rope_base 500000
CPT: max_len 512, lr 2e-4, batch_size 32768, num_steps 100000
Fine-tuning: TODO
Evaluation
MTEB
The results of other models are retrieved from MTEB leaderboard.

The gte evaluation setting: mteb==1.2.0, fp16 auto mix precision, max_length=8192, and set ntk scaling factor to 2 (equivalent to rope_base * 2).

Model Name	Param Size (M)	Dimension	Sequence Length	Average (56)	Class. (12)	Clust. (11)	Pair Class. (3)	Reran. (4)	Retr. (15)	STS (10)	Summ. (1)
gte-large-en-v1.5	434	1024	8192	65.39	77.75	47.95	84.63	58.50	57.91	81.43	30.91
mxbai-embed-large-v1	335	1024	512	64.68	75.64	46.71	87.2	60.11	54.39	85	32.71
multilingual-e5-large-instruct	560	1024	514	64.41	77.56	47.1	86.19	58.58	52.47	84.78	30.39
bge-large-en-v1.5	335	1024	512	64.23	75.97	46.08	87.12	60.03	54.29	83.11	31.61
gte-base-en-v1.5	137	768	8192	64.11	77.17	46.82	85.33	57.66	54.09	81.97	31.17
bge-base-en-v1.5	109	768	512	63.55	75.53	45.77	86.55	58.86	53.25	82.4	31.07
LoCo
Model Name	Dimension	Sequence Length	Average (5)	QsmsumRetrieval	SummScreenRetrieval	QasperAbastractRetrieval	QasperTitleRetrieval	GovReportRetrieval
gte-qwen1.5-7b	4096	32768	87.57	49.37	93.10	99.67	97.54	98.21
gte-large-v1.5	1024	8192	86.71	44.55	92.61	99.82	97.81	98.74
gte-base-v1.5
```

```
instruction = 'Completely irrelevant instruction', expected_confidence = 0.2, expected_scope = 'file-level edit', mock_app_state = <MagicMock id='5577307392'>

    @pytest.mark.asyncio
    @pytest.mark.parametrize("instruction, expected_confidence, expected_scope", [
        ("Add import statement for datetime", 0.20, "file-level edit"),
        ("Update test_function to return True", 0.85, "function"),
        ("Make some changes", 0.2, "file-level edit"),
        ("Completely irrelevant instruction", 0.2, "file-level edit"),
    ])
    async def test_integration_with_real_confidence_scorer(
        instruction, expected_confidence, expected_scope, mock_app_state
    ):
        file_content = """
    def test_function():
        pass
    
    class TestClass:
        def method(self):
            pass
        """
        mock_file = MockFileIO(file_content)
    
        real_open = open  # Preserve the real open function
    
        def mock_open_side_effect(file, mode='r', *args, **kwargs):
            if Path(file).name == "test.py":
                mock_file.seek(0)  # Reset cursor
                return mock_file
            else:
                return real_open(file, mode, *args, **kwargs)  # Use real open
    
        with patch('builtins.open', new=mock_open_side_effect):
            with patch('smart_edit.smart_edit.get_user_approval', return_value=True):
                with patch.object(AIClientFactory, 'get_ai_client', return_value=MockAIClient()):
                    with patch('smart_edit.smart_edit.get_app_state', return_value=mock_app_state):
                        with patch('smart_edit.file_scope_operations.get_app_state', return_value=mock_app_state):
                            with patch('os.path.isfile', side_effect=lambda path: Path(path).name == "test.py"):
                                # Run the smart_edit function with AI model name
                                result = await smart_edit(
                                    file_path="test.py",
                                    instructions=instruction,
                                    model_name="gpt-4-1106-preview"
                                )
    
        # Parse the result
        try:
            result_dict = json.loads(result)
        except json.JSONDecodeError as e:
            pytest.fail(f"Failed to parse JSON result: {e}")
    
        print(f"Instruction: {instruction}")
        print(f"Result: {json.dumps(result_dict, indent=2)}")
    
        # Assertions
>       assert result_dict['status'] == 'success', f"Expected status 'success', but got '{result_dict['status']}'"
E       AssertionError: Expected status 'success', but got 'error'
E       assert 'error' == 'success'
E         
E         - success
E         + error

tests/test_smart_edit/test_smart_edit_integration.py:557: AssertionError
------------------------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------------------------
DEBUG: Using selector: KqueueSelector
-------------------------------------------------------------------------------- Captured log setup ---------------------------------------------------------------------------------
DEBUG    asyncio:selector_events.py:64 Using selector: KqueueSelector
------------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------------
INFO: Starting smart_edit for file: test.py
INFO: Original content:

def test_function():
    pass

class TestClass:
    def method(self):
        pass
    
INFO: Generated EFC with 3 custom tokens
INFO: Custom token: test_function, Type: function_definition
INFO: Custom token: TestClass, Type: class_definition
INFO: Custom token: method, Type: function_definition
INFO: Generated EFC: {
  "custom_tokens": [
    {
      "type": "function_definition",
      "name": "test_function",
      "start": [
        1,
        0
      ],
      "end": [
        2,
        0
      ],
      "depth": 0,
      "code": "def test_function():\n    pass",
      "decorators": [],
      "params": ""
    },
    {
      "type": "class_definition",
      "name": "TestClass",
      "start": [
        4,
        0
      ],
      "end": [
        6,
        0
      ],
      "depth": 0,
      "code": "class TestClass:\n    def method(self):\n        pass",
      "decorators": [],
      "params": ""
    },
    {
      "type": "function_definition",
      "name": "method",
      "start": [
        5,
        0
      ],
      "end": [
        6,
        0
      ],
      "depth": 0,
      "code": "    def method(self):\n        pass",
      "decorators": [],
      "params": "self"
    }
  ],
  "ast_data": [
    {
      "type": "function_definition",
      "name": "test_function",
      "start": [
        1,
        0
      ],
      "end": [
        2,
        0
      ],
      "decorators": [],
      "params": ""
    },
    {
      "type": "class_definition",
      "name": "TestClass",
      "start": [
        4,
        0
      ],
      "end": [
        6,
        0
      ],
      "decorators": [],
      "params": ""
    },
    {
      "type": "function_definition",
      "name": "method",
      "start": [
        5,
        0
      ],
      "end": [
        6,
        0
      ],
      "decorators": [],
      "params": "self"
    }
  ],
  "function_boundaries": [
    {
      "name": "test_function",
      "start_line": 2,
      "end_line": 3,
      "type": "function"
    },
    {
      "name": "TestClass",
      "start_line": 5,
      "end_line": 7,
      "type": "class"
    },
    {
      "name": "method",
      "start_line": 6,
      "end_line": 7,
      "type": "function"
    }
  ],
  "line_structure": [
    {
      "line_number": 1,
      "content": ""
    },
    {
      "line_number": 2,
      "content": "def test_function():"
    },
    {
      "line_number": 3,
      "content": "    pass"
    },
    {
      "line_number": 4,
      "content": ""
    },
    {
      "line_number": 5,
      "content": "class TestClass:"
    },
    {
      "line_number": 6,
      "content": "    def method(self):"
    },
    {
      "line_number": 7,
      "content": "        pass"
    },
    {
      "line_number": 8,
      "content": "    "
    }
  ]
}
INFO: Use pytorch device_name: mps
INFO: Load pretrained SentenceTransformer: Alibaba-NLP/gte-base-en-v1.5
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/modules.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/config_sentence_transformers.json HTTP/11" 404 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/README.md HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/modules.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/sentence_bert_config.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/config.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/new-impl/resolve/main/configuration.py HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/config.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/new-impl/resolve/main/modeling.py HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/model.safetensors HTTP/11" 302 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer_config.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer_config.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/vocab.txt HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/added_tokens.json HTTP/11" 404 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/special_tokens_map.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer_config.json HTTP/11" 200 0
DEBUG: https://huggingface.co:443 "GET /api/models/Alibaba-NLP/gte-base-en-v1.5/revision/main HTTP/11" 200 148931
DEBUG: https://huggingface.co:443 "GET /api/models/Alibaba-NLP/gte-base-en-v1.5 HTTP/11" 200 148931
ERROR: Error in smart_edit: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].
Traceback (most recent call last):
  File "/Users/barry/arc-engineer/.venv/lib/python3.12/site-packages/sentence_transformers/SentenceTransformer.py", line 534, in encode
    prompt = self.prompts[prompt_name]
             ~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: 's2s_query'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/barry/arc-engineer/multi_engineer_v2/smart_edit/smart_edit.py", line 51, in smart_edit
    block_context = find_best_matching_block(efc, instructions)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/multi_engineer_v2/smart_edit/smart_edit.py", line 204, in find_best_matching_block
    scorer = EnhancedConfidenceScorer(efc, query)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/multi_engineer_v2/efc/efc_utils.py", line 1142, in __init__
    super().__init__(efc, query, model_name, device)
  File "/Users/barry/arc-engineer/multi_engineer_v2/efc/efc_utils.py", line 961, in __init__
    self.query_embedding: np.ndarray = self.get_embedding(self.query, prompt_name="s2s_query")
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/multi_engineer_v2/efc/efc_utils.py", line 995, in get_embedding
    embedding = self.model.encode(
                ^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/.venv/lib/python3.12/site-packages/sentence_transformers/SentenceTransformer.py", line 536, in encode
    raise ValueError(
ValueError: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].
INFO: Smart edit error result: {"status": "error", "message": "Error during smart update: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].", "details": "Prompt name 's2s_query' not found in the configured prompts dictionary with keys []."}
Instruction: Completely irrelevant instruction
Result: {
  "status": "error",
  "message": "Error during smart update: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].",
  "details": "Prompt name 's2s_query' not found in the configured prompts dictionary with keys []."
}
------------------------------------------------------------------------------- Captured stderr call --------------------------------------------------------------------------------
A new version of the following files was downloaded from https://huggingface.co/Alibaba-NLP/new-impl:
- configuration.py
. Make sure to double-check they do not contain any added malicious code. To avoid downloading new versions of the code file, you can pin a revision.
A new version of the following files was downloaded from https://huggingface.co/Alibaba-NLP/new-impl:
- modeling.py
. Make sure to double-check they do not contain any added malicious code. To avoid downloading new versions of the code file, you can pin a revision.
--------------------------------------------------------------------------------- Captured log call ---------------------------------------------------------------------------------
INFO     root:smart_edit.py:33 Starting smart_edit for file: test.py
INFO     root:smart_edit.py:46 Original content:

def test_function():
    pass

class TestClass:
    def method(self):
        pass
    
INFO     root:efc_utils.py:28 Generated EFC with 3 custom tokens
INFO     root:efc_utils.py:30 Custom token: test_function, Type: function_definition
INFO     root:efc_utils.py:30 Custom token: TestClass, Type: class_definition
INFO     root:efc_utils.py:30 Custom token: method, Type: function_definition
INFO     root:smart_edit.py:49 Generated EFC: {
  "custom_tokens": [
    {
      "type": "function_definition",
      "name": "test_function",
      "start": [
        1,
        0
      ],
      "end": [
        2,
        0
      ],
      "depth": 0,
      "code": "def test_function():\n    pass",
      "decorators": [],
      "params": ""
    },
    {
      "type": "class_definition",
      "name": "TestClass",
      "start": [
        4,
        0
      ],
      "end": [
        6,
        0
      ],
      "depth": 0,
      "code": "class TestClass:\n    def method(self):\n        pass",
      "decorators": [],
      "params": ""
    },
    {
      "type": "function_definition",
      "name": "method",
      "start": [
        5,
        0
      ],
      "end": [
        6,
        0
      ],
      "depth": 0,
      "code": "    def method(self):\n        pass",
      "decorators": [],
      "params": "self"
    }
  ],
  "ast_data": [
    {
      "type": "function_definition",
      "name": "test_function",
      "start": [
        1,
        0
      ],
      "end": [
        2,
        0
      ],
      "decorators": [],
      "params": ""
    },
    {
      "type": "class_definition",
      "name": "TestClass",
      "start": [
        4,
        0
      ],
      "end": [
        6,
        0
      ],
      "decorators": [],
      "params": ""
    },
    {
      "type": "function_definition",
      "name": "method",
      "start": [
        5,
        0
      ],
      "end": [
        6,
        0
      ],
      "decorators": [],
      "params": "self"
    }
  ],
  "function_boundaries": [
    {
      "name": "test_function",
      "start_line": 2,
      "end_line": 3,
      "type": "function"
    },
    {
      "name": "TestClass",
      "start_line": 5,
      "end_line": 7,
      "type": "class"
    },
    {
      "name": "method",
      "start_line": 6,
      "end_line": 7,
      "type": "function"
    }
  ],
  "line_structure": [
    {
      "line_number": 1,
      "content": ""
    },
    {
      "line_number": 2,
      "content": "def test_function():"
    },
    {
      "line_number": 3,
      "content": "    pass"
    },
    {
      "line_number": 4,
      "content": ""
    },
    {
      "line_number": 5,
      "content": "class TestClass:"
    },
    {
      "line_number": 6,
      "content": "    def method(self):"
    },
    {
      "line_number": 7,
      "content": "        pass"
    },
    {
      "line_number": 8,
      "content": "    "
    }
  ]
}
INFO     sentence_transformers.SentenceTransformer:SentenceTransformer.py:196 Use pytorch device_name: mps
INFO     sentence_transformers.SentenceTransformer:SentenceTransformer.py:204 Load pretrained SentenceTransformer: Alibaba-NLP/gte-base-en-v1.5
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/modules.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/config_sentence_transformers.json HTTP/11" 404 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/README.md HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/modules.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/sentence_bert_config.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/config.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/new-impl/resolve/main/configuration.py HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/config.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/new-impl/resolve/main/modeling.py HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/model.safetensors HTTP/11" 302 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer_config.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer_config.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/vocab.txt HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/added_tokens.json HTTP/11" 404 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/special_tokens_map.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "HEAD /Alibaba-NLP/gte-base-en-v1.5/resolve/main/tokenizer_config.json HTTP/11" 200 0
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "GET /api/models/Alibaba-NLP/gte-base-en-v1.5/revision/main HTTP/11" 200 148931
DEBUG    urllib3.connectionpool:connectionpool.py:546 https://huggingface.co:443 "GET /api/models/Alibaba-NLP/gte-base-en-v1.5 HTTP/11" 200 148931
ERROR    root:smart_edit.py:113 Error in smart_edit: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].
Traceback (most recent call last):
  File "/Users/barry/arc-engineer/.venv/lib/python3.12/site-packages/sentence_transformers/SentenceTransformer.py", line 534, in encode
    prompt = self.prompts[prompt_name]
             ~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: 's2s_query'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/barry/arc-engineer/multi_engineer_v2/smart_edit/smart_edit.py", line 51, in smart_edit
    block_context = find_best_matching_block(efc, instructions)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/multi_engineer_v2/smart_edit/smart_edit.py", line 204, in find_best_matching_block
    scorer = EnhancedConfidenceScorer(efc, query)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/multi_engineer_v2/efc/efc_utils.py", line 1142, in __init__
    super().__init__(efc, query, model_name, device)
  File "/Users/barry/arc-engineer/multi_engineer_v2/efc/efc_utils.py", line 961, in __init__
    self.query_embedding: np.ndarray = self.get_embedding(self.query, prompt_name="s2s_query")
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/multi_engineer_v2/efc/efc_utils.py", line 995, in get_embedding
    embedding = self.model.encode(
                ^^^^^^^^^^^^^^^^^^
  File "/Users/barry/arc-engineer/.venv/lib/python3.12/site-packages/sentence_transformers/SentenceTransformer.py", line 536, in encode
    raise ValueError(
ValueError: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].
INFO     root:smart_edit.py:119 Smart edit error result: {"status": "error", "message": "Error during smart update: Prompt name 's2s_query' not found in the configured prompts dictionary with keys [].", "details": "Prompt name 's2s_query' not found in the configured prompts dictionary with keys []."}
----------------------------------------------------------------------------- Captured stdout teardown ------------------------------------------------------------------------------
DEBUG: Using selector: KqueueSelector
------------------------------------------------------------------------------- Captured log teardown -------------------------------------------------------------------------------
DEBUG    asyncio:selector_events.py:64 Using selector: KqueueSelector
============================================================================== short test summary info ==============================================================================
FAILED tests/test_smart_edit/test_smart_edit_integration.py::test_integration_with_real_confidence_scorer[Add import statement for datetime-0.2-file-level edit] - AssertionError: Expected status 'success', but got 'error'
assert 'error' == 'success'
  
  - success
  + error
FAILED tests/test_smart_edit/test_smart_edit_integration.py::test_integration_with_real_confidence_scorer[Update test_function to return True-0.85-function] - AssertionError: Expected status 'success', but got 'error'
assert 'error' == 'success'
  
  - success
  + error
FAILED tests/test_smart_edit/test_smart_edit_integration.py::test_integration_with_real_confidence_scorer[Make some changes-0.2-file-level edit] - AssertionError: Expected status 'success', but got 'error'
assert 'error' == 'success'
  
  - success
  + error
FAILED tests/test_smart_edit/test_smart_edit_integration.py::test_integration_with_real_confidence_scorer[Completely irrelevant instruction-0.2-file-level edit] - AssertionError: Expected status 'success', but got 'error'
assert 'error' == 'success'
  
  - success
  + error
```