abstractcore 2.9.1__py3-none-any.whl → 2.11.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- abstractcore/__init__.py +7 -27
- abstractcore/apps/deepsearch.py +9 -4
- abstractcore/apps/extractor.py +33 -100
- abstractcore/apps/intent.py +19 -0
- abstractcore/apps/judge.py +20 -1
- abstractcore/apps/summarizer.py +20 -1
- abstractcore/architectures/detection.py +34 -1
- abstractcore/architectures/response_postprocessing.py +313 -0
- abstractcore/assets/architecture_formats.json +38 -8
- abstractcore/assets/model_capabilities.json +882 -160
- abstractcore/compression/__init__.py +1 -2
- abstractcore/compression/glyph_processor.py +6 -4
- abstractcore/config/main.py +52 -20
- abstractcore/config/manager.py +390 -12
- abstractcore/config/vision_config.py +5 -5
- abstractcore/core/interface.py +151 -3
- abstractcore/core/session.py +16 -10
- abstractcore/download.py +1 -1
- abstractcore/embeddings/manager.py +20 -6
- abstractcore/endpoint/__init__.py +2 -0
- abstractcore/endpoint/app.py +458 -0
- abstractcore/mcp/client.py +3 -1
- abstractcore/media/__init__.py +52 -17
- abstractcore/media/auto_handler.py +42 -22
- abstractcore/media/base.py +44 -1
- abstractcore/media/capabilities.py +12 -33
- abstractcore/media/enrichment.py +105 -0
- abstractcore/media/handlers/anthropic_handler.py +19 -28
- abstractcore/media/handlers/local_handler.py +124 -70
- abstractcore/media/handlers/openai_handler.py +19 -31
- abstractcore/media/processors/__init__.py +4 -2
- abstractcore/media/processors/audio_processor.py +57 -0
- abstractcore/media/processors/office_processor.py +8 -3
- abstractcore/media/processors/pdf_processor.py +46 -3
- abstractcore/media/processors/text_processor.py +22 -24
- abstractcore/media/processors/video_processor.py +58 -0
- abstractcore/media/types.py +97 -4
- abstractcore/media/utils/image_scaler.py +20 -2
- abstractcore/media/utils/video_frames.py +219 -0
- abstractcore/media/vision_fallback.py +136 -22
- abstractcore/processing/__init__.py +32 -3
- abstractcore/processing/basic_deepsearch.py +15 -10
- abstractcore/processing/basic_intent.py +3 -2
- abstractcore/processing/basic_judge.py +3 -2
- abstractcore/processing/basic_summarizer.py +1 -1
- abstractcore/providers/__init__.py +3 -1
- abstractcore/providers/anthropic_provider.py +95 -8
- abstractcore/providers/base.py +1516 -81
- abstractcore/providers/huggingface_provider.py +546 -69
- abstractcore/providers/lmstudio_provider.py +30 -916
- abstractcore/providers/mlx_provider.py +382 -35
- abstractcore/providers/model_capabilities.py +5 -1
- abstractcore/providers/ollama_provider.py +99 -15
- abstractcore/providers/openai_compatible_provider.py +406 -180
- abstractcore/providers/openai_provider.py +188 -44
- abstractcore/providers/openrouter_provider.py +76 -0
- abstractcore/providers/registry.py +61 -5
- abstractcore/providers/streaming.py +138 -33
- abstractcore/providers/vllm_provider.py +92 -817
- abstractcore/server/app.py +478 -28
- abstractcore/server/audio_endpoints.py +139 -0
- abstractcore/server/vision_endpoints.py +1319 -0
- abstractcore/structured/handler.py +316 -41
- abstractcore/tools/common_tools.py +5501 -2012
- abstractcore/tools/comms_tools.py +1641 -0
- abstractcore/tools/core.py +37 -7
- abstractcore/tools/handler.py +4 -9
- abstractcore/tools/parser.py +49 -2
- abstractcore/tools/tag_rewriter.py +2 -1
- abstractcore/tools/telegram_tdlib.py +407 -0
- abstractcore/tools/telegram_tools.py +261 -0
- abstractcore/utils/cli.py +1085 -72
- abstractcore/utils/structured_logging.py +29 -8
- abstractcore/utils/token_utils.py +2 -0
- abstractcore/utils/truncation.py +29 -0
- abstractcore/utils/version.py +3 -4
- abstractcore/utils/vlm_token_calculator.py +12 -2
- abstractcore-2.11.4.dist-info/METADATA +562 -0
- abstractcore-2.11.4.dist-info/RECORD +133 -0
- {abstractcore-2.9.1.dist-info → abstractcore-2.11.4.dist-info}/WHEEL +1 -1
- {abstractcore-2.9.1.dist-info → abstractcore-2.11.4.dist-info}/entry_points.txt +1 -0
- abstractcore-2.9.1.dist-info/METADATA +0 -1190
- abstractcore-2.9.1.dist-info/RECORD +0 -119
- {abstractcore-2.9.1.dist-info → abstractcore-2.11.4.dist-info}/licenses/LICENSE +0 -0
- {abstractcore-2.9.1.dist-info → abstractcore-2.11.4.dist-info}/top_level.txt +0 -0
|
@@ -57,7 +57,7 @@ def _get_config_defaults():
|
|
|
57
57
|
"NONE": logging.CRITICAL + 10 # Higher than CRITICAL to effectively disable logging
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
console_level = level_map.get(logging_config.console_level, logging.
|
|
60
|
+
console_level = level_map.get(logging_config.console_level, logging.ERROR)
|
|
61
61
|
file_level = level_map.get(logging_config.file_level, logging.DEBUG)
|
|
62
62
|
|
|
63
63
|
# Use log_base_dir if file logging enabled
|
|
@@ -66,6 +66,27 @@ def _get_config_defaults():
|
|
|
66
66
|
# Expand user home directory
|
|
67
67
|
log_dir = str(Path(logging_config.log_base_dir).expanduser())
|
|
68
68
|
|
|
69
|
+
# Environment overrides (optional)
|
|
70
|
+
env_console = os.getenv("ABSTRACTCORE_CONSOLE_LOG_LEVEL")
|
|
71
|
+
if isinstance(env_console, str) and env_console.strip():
|
|
72
|
+
env_level = env_console.strip().upper()
|
|
73
|
+
if env_level == "NONE":
|
|
74
|
+
console_level = None
|
|
75
|
+
else:
|
|
76
|
+
console_level = level_map.get(env_level, console_level)
|
|
77
|
+
|
|
78
|
+
env_file = os.getenv("ABSTRACTCORE_FILE_LOG_LEVEL")
|
|
79
|
+
if isinstance(env_file, str) and env_file.strip():
|
|
80
|
+
env_level = env_file.strip().upper()
|
|
81
|
+
if env_level == "NONE":
|
|
82
|
+
file_level = None
|
|
83
|
+
else:
|
|
84
|
+
file_level = level_map.get(env_level, file_level)
|
|
85
|
+
|
|
86
|
+
env_log_dir = os.getenv("ABSTRACTCORE_LOG_BASE_DIR")
|
|
87
|
+
if isinstance(env_log_dir, str) and env_log_dir.strip():
|
|
88
|
+
log_dir = str(Path(env_log_dir.strip()).expanduser())
|
|
89
|
+
|
|
69
90
|
return {
|
|
70
91
|
'console_level': console_level,
|
|
71
92
|
'file_level': file_level,
|
|
@@ -77,7 +98,7 @@ def _get_config_defaults():
|
|
|
77
98
|
except Exception:
|
|
78
99
|
# Fallback to hardcoded defaults if config unavailable
|
|
79
100
|
return {
|
|
80
|
-
'console_level': logging.
|
|
101
|
+
'console_level': logging.ERROR,
|
|
81
102
|
'file_level': logging.DEBUG,
|
|
82
103
|
'log_dir': None,
|
|
83
104
|
'verbatim_enabled': True,
|
|
@@ -89,7 +110,7 @@ def _get_config_defaults():
|
|
|
89
110
|
LOG_LEVEL_COLORS = {
|
|
90
111
|
'DEBUG': Fore.CYAN + Style.DIM, # Cyan, dimmed (less prominent)
|
|
91
112
|
'INFO': Fore.GREEN, # Green (informational, good)
|
|
92
|
-
'WARNING':
|
|
113
|
+
'WARNING': "\033[38;5;214m" + Style.BRIGHT, # Orange (attention)
|
|
93
114
|
'ERROR': Fore.RED, # Red (error)
|
|
94
115
|
'CRITICAL': Fore.RED + Style.BRIGHT # Bright red (critical)
|
|
95
116
|
}
|
|
@@ -215,7 +236,7 @@ class LogConfig:
|
|
|
215
236
|
root_logger.handlers.clear()
|
|
216
237
|
|
|
217
238
|
# Console handler
|
|
218
|
-
if self.console_level is not None:
|
|
239
|
+
if self.console_level is not None and self.console_level < (logging.CRITICAL + 10):
|
|
219
240
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
220
241
|
console_handler.setLevel(self.console_level)
|
|
221
242
|
|
|
@@ -260,8 +281,8 @@ class LogConfig:
|
|
|
260
281
|
if effective_levels:
|
|
261
282
|
root_logger.setLevel(min(effective_levels))
|
|
262
283
|
else:
|
|
263
|
-
# No handlers enabled, set to
|
|
264
|
-
root_logger.setLevel(logging.
|
|
284
|
+
# No handlers enabled, set to ERROR as a safe default
|
|
285
|
+
root_logger.setLevel(logging.ERROR)
|
|
265
286
|
|
|
266
287
|
|
|
267
288
|
# Global config instance
|
|
@@ -493,7 +514,7 @@ def get_logger(name: str) -> StructuredLogger:
|
|
|
493
514
|
|
|
494
515
|
|
|
495
516
|
def configure_logging(
|
|
496
|
-
console_level: Optional[int] = logging.
|
|
517
|
+
console_level: Optional[int] = logging.ERROR,
|
|
497
518
|
file_level: Optional[int] = logging.DEBUG,
|
|
498
519
|
log_dir: Optional[str] = None,
|
|
499
520
|
verbatim_enabled: bool = True,
|
|
@@ -577,4 +598,4 @@ def suppress_stdout_stderr():
|
|
|
577
598
|
yield
|
|
578
599
|
finally:
|
|
579
600
|
sys.stdout = old_stdout
|
|
580
|
-
sys.stderr = old_stderr
|
|
601
|
+
sys.stderr = old_stderr
|
|
@@ -230,12 +230,14 @@ class TokenUtils:
|
|
|
230
230
|
return ContentType.NATURAL_LANGUAGE
|
|
231
231
|
|
|
232
232
|
# Sample first 1000 chars for efficiency
|
|
233
|
+
#[WARNING:TRUNCATION] bounded sample for heuristic detection (performance)
|
|
233
234
|
sample = text[:1000]
|
|
234
235
|
|
|
235
236
|
# JSON detection
|
|
236
237
|
if sample.strip().startswith(('{', '[')):
|
|
237
238
|
try:
|
|
238
239
|
import json
|
|
240
|
+
#[WARNING:TRUNCATION] bounded JSON probe for heuristic detection (performance)
|
|
239
241
|
json.loads(sample[:500]) # Try to parse a portion
|
|
240
242
|
return ContentType.JSON
|
|
241
243
|
except:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Truncation utilities (explicit + searchable).
|
|
2
|
+
|
|
3
|
+
Policy authority: ADR-0026 (docs/adr/0026-truncation-policy-and-contract.md).
|
|
4
|
+
|
|
5
|
+
All lossy truncation must:
|
|
6
|
+
- be explicit in the returned text (marker),
|
|
7
|
+
- and be searchable in code via `#[WARNING:TRUNCATION]`.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def preview_text(value: Any, *, max_chars: int, marker: str = "… (truncated)") -> str:
|
|
16
|
+
"""Return `value` as a bounded preview with an explicit truncation marker."""
|
|
17
|
+
s = str(value or "")
|
|
18
|
+
if max_chars <= 0:
|
|
19
|
+
#[WARNING:TRUNCATION] bounded preview requested with max_chars<=0
|
|
20
|
+
return ""
|
|
21
|
+
max_chars_i = int(max_chars)
|
|
22
|
+
if len(s) <= max_chars_i:
|
|
23
|
+
return s
|
|
24
|
+
#[WARNING:TRUNCATION] bounded preview (logs/telemetry/UI)
|
|
25
|
+
keep = max(0, max_chars_i - len(marker))
|
|
26
|
+
if keep <= 0:
|
|
27
|
+
return marker[:max_chars_i].rstrip()
|
|
28
|
+
return s[:keep].rstrip() + marker
|
|
29
|
+
|
abstractcore/utils/version.py
CHANGED
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
Version management for AbstractCore.
|
|
3
3
|
|
|
4
4
|
This module provides the package version as a static constant that serves as the
|
|
5
|
-
single source of truth
|
|
6
|
-
|
|
5
|
+
single source of truth. Packaging reads the version from this module via
|
|
6
|
+
`[tool.setuptools.dynamic]` in `pyproject.toml`.
|
|
7
7
|
|
|
8
8
|
This approach ensures reliable version access in all deployment scenarios,
|
|
9
9
|
including when the package is installed from PyPI where pyproject.toml is not available.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
# Package version - update this when releasing new versions
|
|
13
|
-
|
|
14
|
-
__version__ = "2.9.1"
|
|
13
|
+
__version__ = "2.11.4"
|
|
@@ -24,7 +24,12 @@ from typing import Tuple, Dict, Any, Optional, List
|
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
import logging
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
try:
|
|
28
|
+
from PIL import Image
|
|
29
|
+
PIL_AVAILABLE = True
|
|
30
|
+
except ImportError: # pragma: no cover
|
|
31
|
+
Image = None
|
|
32
|
+
PIL_AVAILABLE = False
|
|
28
33
|
|
|
29
34
|
from ..utils.structured_logging import get_logger
|
|
30
35
|
from ..architectures.detection import get_model_capabilities, detect_architecture
|
|
@@ -143,6 +148,11 @@ class VLMTokenCalculator:
|
|
|
143
148
|
"""
|
|
144
149
|
# Get image dimensions
|
|
145
150
|
if image_path and image_path.exists():
|
|
151
|
+
if not PIL_AVAILABLE:
|
|
152
|
+
raise ImportError(
|
|
153
|
+
"PIL/Pillow is required to read image files for token calculation. "
|
|
154
|
+
"Install with: pip install \"abstractcore[media]\""
|
|
155
|
+
)
|
|
146
156
|
try:
|
|
147
157
|
with Image.open(image_path) as img:
|
|
148
158
|
width, height = img.size
|
|
@@ -653,4 +663,4 @@ def calculate_glyph_compression_ratio(original_tokens: int,
|
|
|
653
663
|
model: str = '') -> Dict[str, Any]:
|
|
654
664
|
"""Calculate accurate Glyph compression ratio."""
|
|
655
665
|
calculator = VLMTokenCalculator()
|
|
656
|
-
return calculator.get_compression_ratio(original_tokens, image_paths, provider, model)
|
|
666
|
+
return calculator.get_compression_ratio(original_tokens, image_paths, provider, model)
|