hivetrace 1.3.4__py3-none-any.whl → 1.3.6__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.
Files changed (37) hide show
  1. hivetrace/__init__.py +118 -9
  2. hivetrace/adapters/base_adapter.py +42 -6
  3. hivetrace/adapters/crewai/adapter.py +220 -289
  4. hivetrace/adapters/crewai/decorators.py +13 -22
  5. hivetrace/adapters/crewai/monitored_crew.py +81 -108
  6. hivetrace/adapters/crewai/tool_wrapper.py +22 -48
  7. hivetrace/adapters/langchain/__init__.py +3 -0
  8. hivetrace/adapters/langchain/adapter.py +67 -0
  9. hivetrace/adapters/langchain/api.py +264 -0
  10. hivetrace/adapters/openai_agents/tracing.py +8 -7
  11. hivetrace/client/__init__.py +15 -0
  12. hivetrace/client/async_client.py +114 -0
  13. hivetrace/client/base.py +180 -0
  14. hivetrace/client/sync_client.py +116 -0
  15. hivetrace/errors/__init__.py +55 -0
  16. hivetrace/errors/api.py +35 -0
  17. hivetrace/errors/base.py +30 -0
  18. hivetrace/errors/network.py +32 -0
  19. hivetrace/errors/validation.py +37 -0
  20. hivetrace/handlers/__init__.py +14 -0
  21. hivetrace/handlers/error_handler.py +119 -0
  22. hivetrace/handlers/response_builder.py +80 -0
  23. hivetrace/models/__init__.py +50 -0
  24. hivetrace/models/requests.py +88 -0
  25. hivetrace/models/responses.py +102 -0
  26. hivetrace/utils/__init__.py +31 -1
  27. hivetrace/utils/error_helpers.py +78 -0
  28. hivetrace/utils/uuid_generator.py +0 -9
  29. hivetrace-1.3.6.dist-info/METADATA +905 -0
  30. hivetrace-1.3.6.dist-info/RECORD +45 -0
  31. hivetrace/crewai_adapter.py +0 -9
  32. hivetrace/hivetrace.py +0 -270
  33. hivetrace-1.3.4.dist-info/METADATA +0 -850
  34. hivetrace-1.3.4.dist-info/RECORD +0 -30
  35. {hivetrace-1.3.4.dist-info → hivetrace-1.3.6.dist-info}/LICENSE +0 -0
  36. {hivetrace-1.3.4.dist-info → hivetrace-1.3.6.dist-info}/WHEEL +0 -0
  37. {hivetrace-1.3.4.dist-info → hivetrace-1.3.6.dist-info}/top_level.txt +0 -0
hivetrace/__init__.py CHANGED
@@ -1,20 +1,110 @@
1
- from .hivetrace import (
2
- HivetraceSDK,
1
+ """
2
+ HiveTrace SDK - Python client for monitoring LLM applications.
3
+ """
4
+
5
+ # Main clients
6
+ from .client import AsyncHivetraceSDK, BaseHivetraceSDK, SyncHivetraceSDK
7
+
8
+ # Exceptions (only exception classes)
9
+ from .errors import (
10
+ APIError,
11
+ ConfigurationError,
12
+ ConnectionError,
13
+ HiveTraceError,
14
+ HTTPError,
15
+ InvalidFormatError,
3
16
  InvalidParameterError,
17
+ JSONDecodeError,
4
18
  MissingConfigError,
19
+ MissingParameterError,
20
+ NetworkError,
21
+ RateLimitError,
22
+ RequestError,
23
+ TimeoutError,
5
24
  UnauthorizedError,
25
+ ValidationError,
26
+ )
27
+
28
+ # Handlers
29
+ from .handlers import ErrorHandler, ResponseBuilder
30
+
31
+ # Data models (Pydantic)
32
+ from .models import (
33
+ FunctionCallRequest,
34
+ HivetraceResponse,
35
+ InputRequest,
36
+ OutputRequest,
37
+ ProcessResponse,
38
+ SuccessResponse,
39
+ )
40
+
41
+ # Utils
42
+ from .utils import (
43
+ generate_uuid,
44
+ get_error_details,
45
+ get_error_type,
46
+ get_status_code,
47
+ is_connection_error,
48
+ is_error_response,
49
+ is_http_error,
50
+ is_json_decode_error,
51
+ is_request_error,
52
+ is_success_response,
53
+ is_timeout_error,
54
+ is_validation_error,
6
55
  )
7
56
 
8
57
  __all__ = [
9
- "HivetraceSDK",
10
- "InvalidParameterError",
58
+ # Main classes
59
+ "AsyncHivetraceSDK",
60
+ "SyncHivetraceSDK",
61
+ "BaseHivetraceSDK",
62
+ # Exceptions
63
+ "HiveTraceError",
64
+ "ConfigurationError",
11
65
  "MissingConfigError",
12
66
  "UnauthorizedError",
67
+ "ValidationError",
68
+ "InvalidParameterError",
69
+ "MissingParameterError",
70
+ "InvalidFormatError",
71
+ "NetworkError",
72
+ "ConnectionError",
73
+ "TimeoutError",
74
+ "RequestError",
75
+ "APIError",
76
+ "HTTPError",
77
+ "JSONDecodeError",
78
+ "RateLimitError",
79
+ # Models
80
+ "HivetraceResponse",
81
+ "SuccessResponse",
82
+ "ProcessResponse",
83
+ "InputRequest",
84
+ "OutputRequest",
85
+ "FunctionCallRequest",
86
+ # Handlers
87
+ "ErrorHandler",
88
+ "ResponseBuilder",
89
+ # Utils
90
+ "generate_uuid",
91
+ "is_error_response",
92
+ "is_success_response",
93
+ "get_error_type",
94
+ "get_error_details",
95
+ "get_status_code",
96
+ "is_connection_error",
97
+ "is_timeout_error",
98
+ "is_http_error",
99
+ "is_json_decode_error",
100
+ "is_request_error",
101
+ "is_validation_error",
13
102
  ]
14
103
 
104
+ # Optional adapters
15
105
  try:
16
- from hivetrace.crewai_adapter import CrewAIAdapter as _CrewAIAdapter
17
- from hivetrace.crewai_adapter import trace as _crewai_trace
106
+ from hivetrace.adapters.crewai import CrewAIAdapter as _CrewAIAdapter
107
+ from hivetrace.adapters.crewai import trace as _crewai_trace
18
108
 
19
109
  CrewAIAdapter = _CrewAIAdapter
20
110
  crewai_trace = _crewai_trace
@@ -25,12 +115,31 @@ except ImportError:
25
115
  pass
26
116
 
27
117
  try:
28
- from hivetrace.adapters.langchain import LangChainAdapter as _LangChainAdapter
29
- from hivetrace.adapters.langchain import trace as _langchain_trace
118
+ from hivetrace.adapters.langchain import (
119
+ LangChainAdapter as _LangChainAdapter,
120
+ )
121
+ from hivetrace.adapters.langchain import (
122
+ run_with_tracing as _run_with_tracing,
123
+ )
124
+ from hivetrace.adapters.langchain import (
125
+ run_with_tracing_async as _run_with_tracing_async,
126
+ )
127
+ from hivetrace.adapters.langchain import (
128
+ trace as _langchain_trace,
129
+ )
30
130
 
31
131
  LangChainAdapter = _LangChainAdapter
32
132
  langchain_trace = _langchain_trace
133
+ run_with_tracing = _run_with_tracing
134
+ run_with_tracing_async = _run_with_tracing_async
33
135
 
34
- __all__.extend(["LangChainAdapter", "langchain_trace"])
136
+ __all__.extend(
137
+ [
138
+ "LangChainAdapter",
139
+ "langchain_trace",
140
+ "run_with_tracing",
141
+ "run_with_tracing_async",
142
+ ]
143
+ )
35
144
  except ImportError:
36
145
  pass
@@ -54,8 +54,14 @@ class BaseAdapter:
54
54
  - additional_params_from_caller: Additional parameters to include in the log
55
55
  """
56
56
  final_additional_params = additional_params_from_caller or {}
57
- final_additional_params.setdefault("user_id", self.user_id)
58
- final_additional_params.setdefault("session_id", self.session_id)
57
+ if hasattr(self, "user_id") and self.user_id is not None and self.user_id != "":
58
+ final_additional_params.setdefault("user_id", self.user_id)
59
+ if (
60
+ hasattr(self, "session_id")
61
+ and self.session_id is not None
62
+ and self.session_id != ""
63
+ ):
64
+ final_additional_params.setdefault("session_id", self.session_id)
59
65
 
60
66
  log_kwargs = {
61
67
  "application_id": self.application_id,
@@ -71,19 +77,49 @@ class BaseAdapter:
71
77
  if tool_call_details is None:
72
78
  print("Warning: tool_call_details is None for function_call")
73
79
  return
74
- log_kwargs.update(tool_call_details)
80
+ merged_tool_details = dict(tool_call_details)
81
+ ap = dict(merged_tool_details.get("additional_parameters", {}) or {})
82
+ if (
83
+ hasattr(self, "user_id")
84
+ and self.user_id is not None
85
+ and self.user_id != ""
86
+ ):
87
+ ap.setdefault("user_id", self.user_id)
88
+ if (
89
+ hasattr(self, "session_id")
90
+ and self.session_id is not None
91
+ and self.session_id != ""
92
+ ):
93
+ ap.setdefault("session_id", self.session_id)
94
+ if ap:
95
+ merged_tool_details["additional_parameters"] = ap
96
+ log_kwargs.update(merged_tool_details)
75
97
  else:
76
98
  print(f"Error: Unsupported log_method_name_stem: {log_method_name_stem}")
77
99
  return
78
100
 
79
- method_to_call_name = f"{log_method_name_stem}{'_async' if is_async else ''}"
101
+ # Both SyncHivetraceSDK and AsyncHivetraceSDK expose the same method names
102
+ # (input/output/function_call). In async mode they are coroutines.
103
+ method_to_call_name = log_method_name_stem
80
104
 
81
105
  try:
82
106
  actual_log_method = getattr(self.trace, method_to_call_name)
83
107
  if is_async:
84
108
  import asyncio
85
-
86
- asyncio.create_task(actual_log_method(**log_kwargs))
109
+ import inspect
110
+
111
+ try:
112
+ maybe_coro = actual_log_method(**log_kwargs)
113
+ except TypeError:
114
+ # Fallback: call without kwargs if signature mismatch (defensive)
115
+ maybe_coro = actual_log_method()
116
+
117
+ if inspect.isawaitable(maybe_coro):
118
+ asyncio.create_task(maybe_coro)
119
+ else:
120
+ # If the method is unexpectedly sync in async mode, call directly
121
+ # to avoid dropping the log.
122
+ pass
87
123
  else:
88
124
  actual_log_method(**log_kwargs)
89
125
  except AttributeError: