diff --git a/open_notebook/ai/models.py b/open_notebook/ai/models.py index 23b6ea8..076340b 100644 --- a/open_notebook/ai/models.py +++ b/open_notebook/ai/models.py @@ -255,7 +255,7 @@ class ModelManager: try: return await self.get_model(model_id, **kwargs) - except ValueError as e: + except (ValueError, ConfigurationError) as e: logger.error( f"Failed to load default model for type '{model_type}': {e}. " f"The configured model_id '{model_id}' may have been deleted or misconfigured. " diff --git a/open_notebook/utils/error_classifier.py b/open_notebook/utils/error_classifier.py index 1f4fc20..8d1e319 100644 --- a/open_notebook/utils/error_classifier.py +++ b/open_notebook/utils/error_classifier.py @@ -80,11 +80,18 @@ def classify_error(exception: BaseException) -> tuple[type[OpenNotebookError], s for keywords, exc_class, message in _CLASSIFICATION_RULES: for keyword in keywords: if keyword in combined: - user_message = message if message is not None else str(exception) + user_message = message if message is not None else _truncate(str(exception)) return exc_class, user_message # Unclassified error - log for future improvement logger.warning( f"Unclassified LLM error ({type(exception).__name__}): {exception}" ) - return ExternalServiceError, f"AI service error: {exception}" + return ExternalServiceError, f"AI service error: {_truncate(str(exception))}" + + +def _truncate(text: str, max_length: int = 200) -> str: + """Truncate text to max_length to avoid leaking verbose internal details.""" + if len(text) <= max_length: + return text + return text[:max_length] + "..." diff --git a/uv.lock b/uv.lock index 06cf623..ef336aa 100644 --- a/uv.lock +++ b/uv.lock @@ -2095,7 +2095,7 @@ wheels = [ [[package]] name = "open-notebook" -version = "1.7.1" +version = "1.7.2" source = { editable = "." } dependencies = [ { name = "ai-prompter" },