abstractcore 2.4.3__py3-none-any.whl → 2.4.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/providers/base.py +97 -0
- abstractcore/providers/huggingface_provider.py +17 -8
- abstractcore/utils/version.py +1 -1
- {abstractcore-2.4.3.dist-info → abstractcore-2.4.4.dist-info}/METADATA +1 -1
- {abstractcore-2.4.3.dist-info → abstractcore-2.4.4.dist-info}/RECORD +9 -9
- {abstractcore-2.4.3.dist-info → abstractcore-2.4.4.dist-info}/WHEEL +0 -0
- {abstractcore-2.4.3.dist-info → abstractcore-2.4.4.dist-info}/entry_points.txt +0 -0
- {abstractcore-2.4.3.dist-info → abstractcore-2.4.4.dist-info}/licenses/LICENSE +0 -0
- {abstractcore-2.4.3.dist-info → abstractcore-2.4.4.dist-info}/top_level.txt +0 -0
abstractcore/providers/base.py
CHANGED
|
@@ -867,6 +867,103 @@ class BaseProvider(AbstractCoreInterface, ABC):
|
|
|
867
867
|
"""
|
|
868
868
|
pass
|
|
869
869
|
|
|
870
|
+
def health(self, timeout: Optional[float] = 5.0) -> Dict[str, Any]:
|
|
871
|
+
"""
|
|
872
|
+
Check provider health and connectivity.
|
|
873
|
+
|
|
874
|
+
This method tests if the provider is online and accessible by attempting
|
|
875
|
+
to list available models. A successful model listing indicates the provider
|
|
876
|
+
is healthy and ready to serve requests.
|
|
877
|
+
|
|
878
|
+
Args:
|
|
879
|
+
timeout: Maximum time in seconds to wait for health check (default: 5.0).
|
|
880
|
+
None means unlimited timeout (not recommended for health checks).
|
|
881
|
+
|
|
882
|
+
Returns:
|
|
883
|
+
Dict with health status information:
|
|
884
|
+
{
|
|
885
|
+
"status": bool, # True if provider is healthy/online
|
|
886
|
+
"provider": str, # Provider class name (e.g., "OpenAIProvider")
|
|
887
|
+
"models": List[str] | None, # Available models if online, None if offline
|
|
888
|
+
"model_count": int, # Number of models available (0 if offline)
|
|
889
|
+
"error": str | None, # Error message if offline, None if healthy
|
|
890
|
+
"latency_ms": float # Time taken for health check in milliseconds
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
Example:
|
|
894
|
+
>>> provider = OllamaProvider(model="llama2")
|
|
895
|
+
>>> health = provider.health(timeout=3.0)
|
|
896
|
+
>>> if health["status"]:
|
|
897
|
+
>>> print(f"Healthy! {health['model_count']} models available")
|
|
898
|
+
>>> else:
|
|
899
|
+
>>> print(f"Offline: {health['error']}")
|
|
900
|
+
|
|
901
|
+
Note:
|
|
902
|
+
- This method never raises exceptions; errors are captured in the response
|
|
903
|
+
- Uses list_available_models() as the connectivity test
|
|
904
|
+
- Providers can override this method for custom health check logic
|
|
905
|
+
"""
|
|
906
|
+
import time as time_module
|
|
907
|
+
|
|
908
|
+
start_time = time_module.time()
|
|
909
|
+
provider_name = self.__class__.__name__
|
|
910
|
+
|
|
911
|
+
try:
|
|
912
|
+
# Attempt to list models as connectivity test
|
|
913
|
+
# Store original timeout if provider has HTTP client
|
|
914
|
+
original_timeout = None
|
|
915
|
+
timeout_changed = False
|
|
916
|
+
|
|
917
|
+
if timeout is not None and hasattr(self, '_timeout'):
|
|
918
|
+
original_timeout = self._timeout
|
|
919
|
+
if original_timeout != timeout:
|
|
920
|
+
self.set_timeout(timeout)
|
|
921
|
+
timeout_changed = True
|
|
922
|
+
|
|
923
|
+
try:
|
|
924
|
+
models = self.list_available_models()
|
|
925
|
+
|
|
926
|
+
# Restore original timeout if changed
|
|
927
|
+
if timeout_changed and original_timeout is not None:
|
|
928
|
+
self.set_timeout(original_timeout)
|
|
929
|
+
|
|
930
|
+
latency_ms = (time_module.time() - start_time) * 1000
|
|
931
|
+
|
|
932
|
+
return {
|
|
933
|
+
"status": True,
|
|
934
|
+
"provider": provider_name,
|
|
935
|
+
"models": models,
|
|
936
|
+
"model_count": len(models) if models else 0,
|
|
937
|
+
"error": None,
|
|
938
|
+
"latency_ms": round(latency_ms, 2)
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
except Exception as e:
|
|
942
|
+
# Restore original timeout on error
|
|
943
|
+
if timeout_changed and original_timeout is not None:
|
|
944
|
+
try:
|
|
945
|
+
self.set_timeout(original_timeout)
|
|
946
|
+
except:
|
|
947
|
+
pass # Best effort restoration
|
|
948
|
+
raise # Re-raise to be caught by outer handler
|
|
949
|
+
|
|
950
|
+
except Exception as e:
|
|
951
|
+
latency_ms = (time_module.time() - start_time) * 1000
|
|
952
|
+
|
|
953
|
+
# Extract meaningful error message
|
|
954
|
+
error_message = str(e)
|
|
955
|
+
if not error_message:
|
|
956
|
+
error_message = f"{type(e).__name__} occurred during health check"
|
|
957
|
+
|
|
958
|
+
return {
|
|
959
|
+
"status": False,
|
|
960
|
+
"provider": provider_name,
|
|
961
|
+
"models": None,
|
|
962
|
+
"model_count": 0,
|
|
963
|
+
"error": error_message,
|
|
964
|
+
"latency_ms": round(latency_ms, 2)
|
|
965
|
+
}
|
|
966
|
+
|
|
870
967
|
def _needs_tag_rewriting(self, tool_call_tags) -> bool:
|
|
871
968
|
"""Check if tag rewriting is needed (tags are non-standard)"""
|
|
872
969
|
try:
|
|
@@ -864,19 +864,14 @@ class HuggingFaceProvider(BaseProvider):
|
|
|
864
864
|
if outputs and len(outputs) > 0:
|
|
865
865
|
response_text = outputs[0]['generated_text'].strip()
|
|
866
866
|
|
|
867
|
-
# Calculate token usage
|
|
868
|
-
|
|
869
|
-
output_tokens = len(self.tokenizer.encode(response_text))
|
|
867
|
+
# Calculate token usage using centralized utilities
|
|
868
|
+
usage = self._calculate_usage(input_text, response_text)
|
|
870
869
|
|
|
871
870
|
return GenerateResponse(
|
|
872
871
|
content=response_text,
|
|
873
872
|
model=self.model,
|
|
874
873
|
finish_reason="stop",
|
|
875
|
-
usage=
|
|
876
|
-
"prompt_tokens": input_tokens,
|
|
877
|
-
"completion_tokens": output_tokens,
|
|
878
|
-
"total_tokens": input_tokens + output_tokens
|
|
879
|
-
}
|
|
874
|
+
usage=usage
|
|
880
875
|
)
|
|
881
876
|
else:
|
|
882
877
|
return GenerateResponse(
|
|
@@ -892,6 +887,20 @@ class HuggingFaceProvider(BaseProvider):
|
|
|
892
887
|
finish_reason="error"
|
|
893
888
|
)
|
|
894
889
|
|
|
890
|
+
def _calculate_usage(self, prompt: str, response: str) -> Dict[str, int]:
|
|
891
|
+
"""Calculate token usage using centralized token utilities."""
|
|
892
|
+
from ..utils.token_utils import TokenUtils
|
|
893
|
+
|
|
894
|
+
prompt_tokens = TokenUtils.estimate_tokens(prompt, self.model)
|
|
895
|
+
completion_tokens = TokenUtils.estimate_tokens(response, self.model)
|
|
896
|
+
total_tokens = prompt_tokens + completion_tokens
|
|
897
|
+
|
|
898
|
+
return {
|
|
899
|
+
"prompt_tokens": prompt_tokens,
|
|
900
|
+
"completion_tokens": completion_tokens,
|
|
901
|
+
"total_tokens": total_tokens
|
|
902
|
+
}
|
|
903
|
+
|
|
895
904
|
def _stream_generate_transformers(self, input_text: str, max_new_tokens: int,
|
|
896
905
|
temperature: float, top_p: float, tool_call_tags: Optional[str] = None) -> Iterator[GenerateResponse]:
|
|
897
906
|
"""Stream response using transformers (simulated, original implementation) with tool tag rewriting support"""
|
abstractcore/utils/version.py
CHANGED
|
@@ -11,4 +11,4 @@ including when the package is installed from PyPI where pyproject.toml is not av
|
|
|
11
11
|
|
|
12
12
|
# Package version - update this when releasing new versions
|
|
13
13
|
# This must be manually synchronized with the version in pyproject.toml
|
|
14
|
-
__version__ = "2.4.
|
|
14
|
+
__version__ = "2.4.4"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstractcore
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.4
|
|
4
4
|
Summary: Unified interface to all LLM providers with essential infrastructure for tool calling, streaming, and model management
|
|
5
5
|
Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
6
6
|
Maintainer-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
@@ -35,8 +35,8 @@ abstractcore/processing/basic_judge.py,sha256=tKWJrg_tY4vCHzWgXxz0ZjgLXBYYfpMcpG
|
|
|
35
35
|
abstractcore/processing/basic_summarizer.py,sha256=XHNxMQ_8aLStTeUo6_2JaThlct12Htpz7ORmm0iuJsg,25495
|
|
36
36
|
abstractcore/providers/__init__.py,sha256=t8Kp4flH5GvZEC6dx-iYJSPeSxMODa2spXb8MqtlPy4,1282
|
|
37
37
|
abstractcore/providers/anthropic_provider.py,sha256=tcOrARLd1kA4vRkH7MCgy99YIGVaegdCd3-Z8UaKP3Q,20705
|
|
38
|
-
abstractcore/providers/base.py,sha256=
|
|
39
|
-
abstractcore/providers/huggingface_provider.py,sha256=
|
|
38
|
+
abstractcore/providers/base.py,sha256=5YR64kqTYiCvWtIUBul5QfO0XRZr6_Aiho4atpDOh0o,50579
|
|
39
|
+
abstractcore/providers/huggingface_provider.py,sha256=mJGfi1lgsvjV3Lj4q7KCQZhQqw_o23af40i5WLg150o,47789
|
|
40
40
|
abstractcore/providers/lmstudio_provider.py,sha256=oPL_Y4gkJMAniecdWQVaDi7WozCZumSRs0lE7uFgvQk,20406
|
|
41
41
|
abstractcore/providers/mlx_provider.py,sha256=61i5VhpNw_QlhOwPcEcryaGbI45aYyL9q15TrpinIgs,17427
|
|
42
42
|
abstractcore/providers/mock_provider.py,sha256=tIjA57Hlwu3vNODOZShNn0tY9HWvz1p4z-HyD_bsvbo,5741
|
|
@@ -63,10 +63,10 @@ abstractcore/utils/message_preprocessor.py,sha256=GdHkm6tmrgjm3PwHRSCjIsq1XLkbhy
|
|
|
63
63
|
abstractcore/utils/self_fixes.py,sha256=QEDwNTW80iQM4ftfEY3Ghz69F018oKwLM9yeRCYZOvw,5886
|
|
64
64
|
abstractcore/utils/structured_logging.py,sha256=Vm-HviSa42G9DJCWmaEv4a0QG3NMsADD3ictLOs4En0,19952
|
|
65
65
|
abstractcore/utils/token_utils.py,sha256=eLwFmJ68p9WMFD_MHLMmeJRW6Oqx_4hKELB8FNQ2Mnk,21097
|
|
66
|
-
abstractcore/utils/version.py,sha256=
|
|
67
|
-
abstractcore-2.4.
|
|
68
|
-
abstractcore-2.4.
|
|
69
|
-
abstractcore-2.4.
|
|
70
|
-
abstractcore-2.4.
|
|
71
|
-
abstractcore-2.4.
|
|
72
|
-
abstractcore-2.4.
|
|
66
|
+
abstractcore/utils/version.py,sha256=ykpU7S-ZbOgwDZo_6zYttC6y8VPe3CuV0anATrFRej8,605
|
|
67
|
+
abstractcore-2.4.4.dist-info/licenses/LICENSE,sha256=PI2v_4HMvd6050uDD_4AY_8PzBnu2asa3RKbdDjowTA,1078
|
|
68
|
+
abstractcore-2.4.4.dist-info/METADATA,sha256=h6Wn0s43Xlng3K0bOw4o1LcT293rVoRPgionXu3kQKg,27596
|
|
69
|
+
abstractcore-2.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
70
|
+
abstractcore-2.4.4.dist-info/entry_points.txt,sha256=di-rxy4iD6A3j8DmQHeVmXYlncgCJKZGamyjrQXEfcU,357
|
|
71
|
+
abstractcore-2.4.4.dist-info/top_level.txt,sha256=DiNHBI35SIawW3N9Z-z0y6cQYNbXd32pvBkW0RLfScs,13
|
|
72
|
+
abstractcore-2.4.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|