beekeeper-core 1.0.10__py3-none-any.whl → 1.0.12__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.
- beekeeper/core/llms/base.py +4 -3
- beekeeper/core/llms/decorators.py +17 -82
- beekeeper/core/llms/types.py +20 -0
- beekeeper/core/monitors/base.py +1 -1
- beekeeper/core/monitors/types.py +4 -1
- {beekeeper_core-1.0.10.dist-info → beekeeper_core-1.0.12.dist-info}/METADATA +1 -1
- {beekeeper_core-1.0.10.dist-info → beekeeper_core-1.0.12.dist-info}/RECORD +8 -8
- {beekeeper_core-1.0.10.dist-info → beekeeper_core-1.0.12.dist-info}/WHEEL +0 -0
beekeeper/core/llms/base.py
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, Optional
|
|
3
3
|
|
|
4
4
|
from beekeeper.core.llms.types import ChatMessage, ChatResponse, GenerateResponse
|
|
5
5
|
from beekeeper.core.monitors import BaseMonitor
|
|
6
6
|
from pydantic import BaseModel
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class BaseLLM(
|
|
9
|
+
class BaseLLM(BaseModel, ABC):
|
|
10
10
|
"""Abstract base class defining the interface for LLMs."""
|
|
11
11
|
|
|
12
12
|
model_config = {"arbitrary_types_allowed": True}
|
|
13
|
+
model: str
|
|
13
14
|
callback_manager: Optional[BaseMonitor] = None
|
|
14
15
|
|
|
15
16
|
@classmethod
|
|
@@ -34,6 +35,6 @@ class BaseLLM(ABC, BaseModel):
|
|
|
34
35
|
|
|
35
36
|
@abstractmethod
|
|
36
37
|
def chat_completion(
|
|
37
|
-
self, messages:
|
|
38
|
+
self, messages: list[ChatMessage | dict], **kwargs: Any
|
|
38
39
|
) -> ChatResponse:
|
|
39
40
|
"""Generates a chat completion for LLM."""
|
|
@@ -6,17 +6,12 @@ from typing import Callable
|
|
|
6
6
|
|
|
7
7
|
from beekeeper.core.llms.types import ChatMessage
|
|
8
8
|
from beekeeper.core.monitors.types import PayloadRecord
|
|
9
|
-
from
|
|
9
|
+
from beekeeper.core.prompts.utils import extract_template_vars
|
|
10
10
|
|
|
11
11
|
logger = getLogger(__name__)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
reason="'llm_chat_observer()' is deprecated and will be removed in a future version. Use 'llm_chat_monitor()'.",
|
|
16
|
-
version="1.0.8",
|
|
17
|
-
action="always",
|
|
18
|
-
)
|
|
19
|
-
def llm_chat_observer() -> Callable:
|
|
14
|
+
def llm_chat_monitor() -> Callable:
|
|
20
15
|
"""
|
|
21
16
|
Decorator to wrap a method with llm handler logic.
|
|
22
17
|
Looks for observability instances in `self.callback_manager`.
|
|
@@ -60,89 +55,29 @@ def llm_chat_observer() -> Callable:
|
|
|
60
55
|
system_messages[0].content if system_messages else None
|
|
61
56
|
)
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"completion_tokens"
|
|
69
|
-
],
|
|
70
|
-
input_token_count=llm_return_val.raw["usage"][
|
|
71
|
-
"prompt_tokens"
|
|
72
|
-
],
|
|
73
|
-
response_time=response_time,
|
|
58
|
+
# Extract template variables values from the prompt template if available
|
|
59
|
+
template_var_values = (
|
|
60
|
+
extract_template_vars(
|
|
61
|
+
callback_manager_fns.prompt_template.template,
|
|
62
|
+
(system_message or ""),
|
|
74
63
|
)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if asyncio.iscoroutine(callback):
|
|
78
|
-
asyncio.run(callback)
|
|
79
|
-
|
|
80
|
-
except Exception as e:
|
|
81
|
-
logger.error(f"Observability callback error: {e}")
|
|
82
|
-
|
|
83
|
-
threading.Thread(target=async_callback_thread).start()
|
|
84
|
-
|
|
85
|
-
return llm_return_val
|
|
86
|
-
|
|
87
|
-
return async_wrapper
|
|
88
|
-
|
|
89
|
-
return decorator
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def llm_chat_monitor() -> Callable:
|
|
93
|
-
"""
|
|
94
|
-
Decorator to wrap a method with llm handler logic.
|
|
95
|
-
Looks for observability instances in `self.callback_manager`.
|
|
96
|
-
"""
|
|
97
|
-
|
|
98
|
-
def decorator(f: Callable) -> Callable:
|
|
99
|
-
def async_wrapper(self, *args, **kwargs):
|
|
100
|
-
callback_manager_fns = getattr(self, "callback_manager", None)
|
|
101
|
-
|
|
102
|
-
start_time = time.time()
|
|
103
|
-
llm_return_val = f(self, *args, **kwargs)
|
|
104
|
-
response_time = int((time.time() - start_time) * 1000)
|
|
105
|
-
|
|
106
|
-
if callback_manager_fns:
|
|
107
|
-
|
|
108
|
-
def async_callback_thread():
|
|
109
|
-
try:
|
|
110
|
-
# Extract input messages
|
|
111
|
-
if len(args) > 0 and isinstance(args[0], ChatMessage):
|
|
112
|
-
input_chat_messages = args[0]
|
|
113
|
-
elif "messages" in kwargs:
|
|
114
|
-
input_chat_messages = kwargs["messages"]
|
|
115
|
-
else:
|
|
116
|
-
raise ValueError(
|
|
117
|
-
"No messages provided in positional or keyword arguments"
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Get the user's latest message after each interaction to chat observability.
|
|
121
|
-
user_messages = [
|
|
122
|
-
msg for msg in input_chat_messages if msg.role == "user"
|
|
123
|
-
]
|
|
124
|
-
last_user_message = (
|
|
125
|
-
user_messages[-1].content if user_messages else None
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
# Get the system/instruct (first) message to chat observability.
|
|
129
|
-
system_messages = [
|
|
130
|
-
msg for msg in input_chat_messages if msg.role == "system"
|
|
131
|
-
]
|
|
132
|
-
system_message = (
|
|
133
|
-
system_messages[0].content if system_messages else None
|
|
64
|
+
if callback_manager_fns.prompt_template
|
|
65
|
+
else {}
|
|
134
66
|
)
|
|
135
67
|
|
|
136
68
|
callback = callback_manager_fns(
|
|
137
69
|
payload=PayloadRecord(
|
|
138
|
-
|
|
70
|
+
system_prompt=(system_message or ""),
|
|
71
|
+
input_text=last_user_message,
|
|
72
|
+
prompt_variables=list(template_var_values.keys()),
|
|
73
|
+
prompt_variable_values=template_var_values,
|
|
139
74
|
generated_text=llm_return_val.message.content,
|
|
140
|
-
generated_token_count=llm_return_val.raw["usage"][
|
|
141
|
-
"completion_tokens"
|
|
142
|
-
],
|
|
143
75
|
input_token_count=llm_return_val.raw["usage"][
|
|
144
76
|
"prompt_tokens"
|
|
145
77
|
],
|
|
78
|
+
generated_token_count=llm_return_val.raw["usage"][
|
|
79
|
+
"completion_tokens"
|
|
80
|
+
],
|
|
146
81
|
response_time=response_time,
|
|
147
82
|
)
|
|
148
83
|
)
|
|
@@ -151,7 +86,7 @@ def llm_chat_monitor() -> Callable:
|
|
|
151
86
|
asyncio.run(callback)
|
|
152
87
|
|
|
153
88
|
except Exception as e:
|
|
154
|
-
logger.error(f"Observability callback
|
|
89
|
+
logger.error(f"Observability callback: {e}")
|
|
155
90
|
|
|
156
91
|
threading.Thread(target=async_callback_thread).start()
|
|
157
92
|
|
beekeeper/core/llms/types.py
CHANGED
|
@@ -22,6 +22,26 @@ class ChatMessage(BaseModel):
|
|
|
22
22
|
"""Convert ChatMessage to dict."""
|
|
23
23
|
return self.model_dump(exclude_none=True)
|
|
24
24
|
|
|
25
|
+
@classmethod
|
|
26
|
+
def from_value(cls, value: dict) -> "ChatMessage":
|
|
27
|
+
if value is None:
|
|
28
|
+
raise ValueError("Invalid 'ChatMessage', cannot be None")
|
|
29
|
+
|
|
30
|
+
if isinstance(value, cls):
|
|
31
|
+
return value
|
|
32
|
+
|
|
33
|
+
if isinstance(value, dict):
|
|
34
|
+
try:
|
|
35
|
+
return cls.model_validate(value)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
raise ValueError(
|
|
38
|
+
"Invalid 'ChatMessage' dict. Received: '{}'.".format(e)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
raise TypeError(
|
|
42
|
+
f"Invalid 'ChatMessage' type. Expected dict or ChatMessage, but received {type(value).__name__}."
|
|
43
|
+
)
|
|
44
|
+
|
|
25
45
|
|
|
26
46
|
class GenerateResponse(BaseModel):
|
|
27
47
|
"""Generate response."""
|
beekeeper/core/monitors/base.py
CHANGED
|
@@ -17,7 +17,7 @@ class PromptMonitor(BaseMonitor):
|
|
|
17
17
|
"""Abstract base class defining the interface for prompt observability."""
|
|
18
18
|
|
|
19
19
|
def __init__(self, prompt_template: Optional[PromptTemplate] = None) -> None:
|
|
20
|
-
self.prompt_template = prompt_template
|
|
20
|
+
self.prompt_template = PromptTemplate.from_value(prompt_template)
|
|
21
21
|
|
|
22
22
|
@classmethod
|
|
23
23
|
def class_name(cls) -> str:
|
beekeeper/core/monitors/types.py
CHANGED
|
@@ -4,8 +4,11 @@ from pydantic import BaseModel
|
|
|
4
4
|
class PayloadRecord(BaseModel):
|
|
5
5
|
"""Payload record."""
|
|
6
6
|
|
|
7
|
+
system_prompt: str | None = None
|
|
7
8
|
input_text: str
|
|
9
|
+
prompt_variables: list[str] | None = None
|
|
10
|
+
prompt_variable_values: dict[str, str] | None = None
|
|
8
11
|
generated_text: str
|
|
9
|
-
generated_token_count: int
|
|
10
12
|
input_token_count: int
|
|
13
|
+
generated_token_count: int
|
|
11
14
|
response_time: int
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: beekeeper-core
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.12
|
|
4
4
|
Summary: Load any data in one line of code and connect with AI applications
|
|
5
5
|
Project-URL: Repository, https://github.com/beekeeper-ai/beekeeper
|
|
6
6
|
Author-email: Leonardo Furnielis <leonardofurnielis@outlook.com>
|
|
@@ -12,12 +12,12 @@ beekeeper/core/guardrails/__init__.py,sha256=onznwYWAyOaxOVeYZle7oDtj3QJODQvJHcf
|
|
|
12
12
|
beekeeper/core/guardrails/base.py,sha256=T-Ywr80iTL0EFYarCymFEEI3QkMsrw27JVh_0407sEU,427
|
|
13
13
|
beekeeper/core/guardrails/types.py,sha256=7sgw1S5BZY0OqO-n04pHXPU7sG-NEZJlQyIeb2Fsq9Q,359
|
|
14
14
|
beekeeper/core/llms/__init__.py,sha256=PN-5Y_Km_l2vO8v9d7iJ6_5xPCZJBh8UzwqRvQZlmTo,250
|
|
15
|
-
beekeeper/core/llms/base.py,sha256=
|
|
16
|
-
beekeeper/core/llms/decorators.py,sha256=
|
|
17
|
-
beekeeper/core/llms/types.py,sha256=
|
|
15
|
+
beekeeper/core/llms/base.py,sha256=fxjOJJR3pNJxtvkICr0Nq9A9wnqf3SMM4cm4sAhA9-o,1308
|
|
16
|
+
beekeeper/core/llms/decorators.py,sha256=KzU5VrHrXpJBHWqDl0lUxeqrUHmaPiJovEeUTM_RNeU,4036
|
|
17
|
+
beekeeper/core/llms/types.py,sha256=ttPCZ3VYtY6tx-E6VIOTicflYMJ3m0aw1znZeYAEVu8,1489
|
|
18
18
|
beekeeper/core/monitors/__init__.py,sha256=TvoiIUJtWRO_4zqCICsFaGl_v4Tpvft1M542Bi13pOI,112
|
|
19
|
-
beekeeper/core/monitors/base.py,sha256=
|
|
20
|
-
beekeeper/core/monitors/types.py,sha256=
|
|
19
|
+
beekeeper/core/monitors/base.py,sha256=_MY0AXCqlLpptwBEOpIfw-lCfRog4rXe_WALPvkHFNk,1007
|
|
20
|
+
beekeeper/core/monitors/types.py,sha256=kAA0g6YT_Menlc0HLPl87Rk9o4r2TybGfLlzuGlL40Y,357
|
|
21
21
|
beekeeper/core/observers/__init__.py,sha256=Z5sDAajai4QLdGIrjq-vr5eJEBhriMMCw5u46j6xHvA,149
|
|
22
22
|
beekeeper/core/observers/base.py,sha256=y1SE_0WQusKhVomFuZCkk42Jb7r93ZS6r_j8vs_Y_r4,1203
|
|
23
23
|
beekeeper/core/observers/types.py,sha256=s-4tB8OdeaCUIRvi6FLuib2u4Yl9evqQdCundNREXQY,217
|
|
@@ -38,6 +38,6 @@ beekeeper/core/tools/base.py,sha256=A6TXn7g3DAZMREYAobfVlyOBuJn_8mIeCByc5412L9Y,
|
|
|
38
38
|
beekeeper/core/utils/pairwise.py,sha256=cpi8GItPFSYP4sjB5zgTFHi6JfBVWsMnNu8koA9VYQU,536
|
|
39
39
|
beekeeper/core/vector_stores/__init__.py,sha256=R5SRG3YpOZqRwIfBLB8KVV6FALWqhIzIhCjRGj-bwPc,93
|
|
40
40
|
beekeeper/core/vector_stores/base.py,sha256=YFW1ioZbFEcJovAh0ZCpHnj0eiXtZvqy_pj2lxPS92k,1652
|
|
41
|
-
beekeeper_core-1.0.
|
|
42
|
-
beekeeper_core-1.0.
|
|
43
|
-
beekeeper_core-1.0.
|
|
41
|
+
beekeeper_core-1.0.12.dist-info/METADATA,sha256=6ZkWc4BXq7HnmKUADUKCmRGR2QRPLHVd1dxegvYUj-k,1331
|
|
42
|
+
beekeeper_core-1.0.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
43
|
+
beekeeper_core-1.0.12.dist-info/RECORD,,
|
|
File without changes
|