beekeeper-ai 0.6.6__py3-none-any.whl → 1.0.1__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/_bundle/__init__.py +0 -0
- beekeeper_ai-1.0.1.dist-info/METADATA +46 -0
- beekeeper_ai-1.0.1.dist-info/RECORD +5 -0
- {beekeeper_ai-0.6.6.dist-info → beekeeper_ai-1.0.1.dist-info}/WHEEL +1 -1
- beekeeper_ai-1.0.1.dist-info/licenses/LICENSE +176 -0
- beekeeper/__init__.py +0 -1
- beekeeper/core/document/__init__.py +0 -6
- beekeeper/core/document/schema.py +0 -97
- beekeeper/core/document_loaders/__init__.py +0 -5
- beekeeper/core/document_loaders/base.py +0 -24
- beekeeper/core/embeddings/__init__.py +0 -6
- beekeeper/core/embeddings/base.py +0 -44
- beekeeper/core/text_splitters/utils.py +0 -142
- beekeeper/core/utils/pairwise.py +0 -20
- beekeeper/document_loaders/__init__.py +0 -17
- beekeeper/document_loaders/directory.py +0 -65
- beekeeper/document_loaders/docx.py +0 -31
- beekeeper/document_loaders/html.py +0 -77
- beekeeper/document_loaders/json.py +0 -53
- beekeeper/document_loaders/pdf.py +0 -38
- beekeeper/document_loaders/s3.py +0 -72
- beekeeper/document_loaders/watson_discovery.py +0 -121
- beekeeper/embeddings/__init__.py +0 -7
- beekeeper/embeddings/huggingface.py +0 -66
- beekeeper/embeddings/watsonx.py +0 -100
- beekeeper/evaluation/__init__.py +0 -5
- beekeeper/evaluation/knowledge_base_coverage.py +0 -62
- beekeeper/monitor/__init__.py +0 -11
- beekeeper/monitor/watsonx.py +0 -843
- beekeeper/retrievers/__init__.py +0 -5
- beekeeper/retrievers/watson_discovery.py +0 -121
- beekeeper/text_splitters/__init__.py +0 -9
- beekeeper/text_splitters/semantic.py +0 -139
- beekeeper/text_splitters/sentence.py +0 -107
- beekeeper/text_splitters/token.py +0 -101
- beekeeper/vector_stores/__init__.py +0 -7
- beekeeper/vector_stores/chroma.py +0 -115
- beekeeper/vector_stores/elasticsearch.py +0 -183
- beekeeper_ai-0.6.6.dist-info/LICENSE +0 -7
- beekeeper_ai-0.6.6.dist-info/METADATA +0 -49
- beekeeper_ai-0.6.6.dist-info/RECORD +0 -37
beekeeper/monitor/watsonx.py
DELETED
|
@@ -1,843 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
import uuid
|
|
4
|
-
from typing import Any, List, Literal
|
|
5
|
-
|
|
6
|
-
logging.getLogger("ibm_watsonx_ai.client").setLevel(logging.ERROR)
|
|
7
|
-
logging.getLogger("ibm_watsonx_ai.wml_resource").setLevel(logging.ERROR)
|
|
8
|
-
|
|
9
|
-
REGIONS_URL = {
|
|
10
|
-
"us-south": {"wml": "https://us-south.ml.cloud.ibm.com",
|
|
11
|
-
"wos": "https://api.aiopenscale.cloud.ibm.com",
|
|
12
|
-
"factsheet": None},
|
|
13
|
-
"eu-de": {"wml": "https://eu-de.ml.cloud.ibm.com",
|
|
14
|
-
"wos": "https://eu-de.api.aiopenscale.cloud.ibm.com",
|
|
15
|
-
"factsheet": "frankfurt"},
|
|
16
|
-
"au-syd": {"wml": "https://au-syd.ml.cloud.ibm.com",
|
|
17
|
-
"wos": "https://au-syd.api.aiopenscale.cloud.ibm.com",
|
|
18
|
-
"factsheet": "sydney"},
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
def _filter_dict(original_dict: dict, optional_keys: List, required_keys: List = []):
|
|
22
|
-
"""Filters a dictionary to keep only the specified keys and check required.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
original_dict (dict): The original dictionary
|
|
26
|
-
optional_keys (list): A list of keys to keep
|
|
27
|
-
required_keys (list, optional): A list of keys that must exist in the dictionary
|
|
28
|
-
"""
|
|
29
|
-
# Ensure all required keys are in the source dictionary
|
|
30
|
-
missing_keys = [key for key in required_keys if key not in original_dict]
|
|
31
|
-
if missing_keys:
|
|
32
|
-
raise KeyError(f"Missing required parameter: {missing_keys}")
|
|
33
|
-
|
|
34
|
-
all_keys_to_keep = set(required_keys + optional_keys)
|
|
35
|
-
|
|
36
|
-
# Create a new dictionary with only the key-value pairs where the key is in 'keys' and value is not None
|
|
37
|
-
return {key: original_dict[key] for key in all_keys_to_keep if key in original_dict and original_dict[key] is not None}
|
|
38
|
-
|
|
39
|
-
def _convert_payload_format(records: List[dict], feature_fields: List[str]) -> List[dict]:
|
|
40
|
-
|
|
41
|
-
payload_data = []
|
|
42
|
-
response_fields = ["generated_text", "input_token_count", "generated_token_count"]
|
|
43
|
-
|
|
44
|
-
for record in records:
|
|
45
|
-
request = { "parameters": { "template_variables": {}}}
|
|
46
|
-
results = {}
|
|
47
|
-
|
|
48
|
-
request["parameters"]["template_variables"] = {field: str(record.get(field, "")) for field in feature_fields}
|
|
49
|
-
|
|
50
|
-
results = {field: record.get(field) for field in response_fields if record.get(field)}
|
|
51
|
-
|
|
52
|
-
pl_record = {"request": request, "response": {"results": [results]}}
|
|
53
|
-
payload_data.append(pl_record)
|
|
54
|
-
|
|
55
|
-
return payload_data
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class CloudPakforDataCredentials:
|
|
59
|
-
"""Encapsulate passed credentials for CloudPakforData.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
url (str): Host URL of Cloud Pak for Data environment.
|
|
63
|
-
api_key (str, optional): Environment api_key if IAM enabled.
|
|
64
|
-
username (str, optional): Environment username.
|
|
65
|
-
password (str, optional): Environment password.
|
|
66
|
-
bedrock_url (str, optional): Bedrock URL. This url is required only when iam-integration is enabled on CP4D 4.0.x cluster.
|
|
67
|
-
instance_id (str, optional): Instance ID.
|
|
68
|
-
version (str, optional): CPD Version.
|
|
69
|
-
disable_ssl_verification (bool, optional): Indicates whether verification of the server's SSL certificate. Defaults to ``True``.
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
def __init__(self,
|
|
73
|
-
url: str,
|
|
74
|
-
api_key: str = None,
|
|
75
|
-
username: str = None,
|
|
76
|
-
password: str = None,
|
|
77
|
-
bedrock_url: str = None,
|
|
78
|
-
instance_id: Literal["icp","openshift"] = None,
|
|
79
|
-
version: str = None,
|
|
80
|
-
disable_ssl_verification: bool = True) -> None:
|
|
81
|
-
|
|
82
|
-
self.url = url
|
|
83
|
-
self.api_key = api_key
|
|
84
|
-
self.username = username
|
|
85
|
-
self.api_key = api_key
|
|
86
|
-
self.password = password
|
|
87
|
-
self.bedrock_url = bedrock_url
|
|
88
|
-
self.instance_id = instance_id
|
|
89
|
-
self.api_key = api_key
|
|
90
|
-
self.version = version
|
|
91
|
-
self.disable_ssl_verification = disable_ssl_verification
|
|
92
|
-
|
|
93
|
-
def to_dict(self) -> dict[str, Any]:
|
|
94
|
-
data = dict([(k, v) for k, v in self.__dict__.items()])
|
|
95
|
-
|
|
96
|
-
if "instance_id" in data and self.instance_id.lower() not in ["icp","openshift"]:
|
|
97
|
-
data.pop("instance_id")
|
|
98
|
-
|
|
99
|
-
return data
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
class WatsonxExternalPromptMonitoring:
|
|
103
|
-
"""Provides functionality to interact with IBM watsonx.governance for monitoring external LLM's.
|
|
104
|
-
|
|
105
|
-
Note:
|
|
106
|
-
One of these parameters is required to create prompt monitor: ``project_id`` or ``space_id``. Not both.
|
|
107
|
-
|
|
108
|
-
Args:
|
|
109
|
-
api_key (str): IBM watsonx.governance API key.
|
|
110
|
-
space_id (str, optional): watsonx.governance space_id.
|
|
111
|
-
project_id (str, optional): watsonx.governance project_id.
|
|
112
|
-
region (str, optional): Region where the watsonx.governance is hosted when using IBM Cloud. Defaults to ``us-south``
|
|
113
|
-
cpd_creds (CloudPakforDataCredentials, optional): Cloud Pak for Data environment details.
|
|
114
|
-
|
|
115
|
-
**Example**
|
|
116
|
-
|
|
117
|
-
.. code-block:: python
|
|
118
|
-
|
|
119
|
-
from beekeeper.monitor import WatsonxExternalPromptMonitoring
|
|
120
|
-
|
|
121
|
-
# watsonx.governance (IBM Cloud)
|
|
122
|
-
detached_watsonx_monitor = WatsonxExternalPromptMonitoring(api_key="your_api_key",
|
|
123
|
-
space_id="your_space_id")
|
|
124
|
-
|
|
125
|
-
# watsonx.governance (cp4d)
|
|
126
|
-
from beekeeper.monitor import CloudPakforDataCredentials
|
|
127
|
-
|
|
128
|
-
cpd_creds = CloudPakforDataCredentials(url="your_cpd_url",
|
|
129
|
-
username="your_username", password="your_password",
|
|
130
|
-
version="5.0", instance_id="openshift")
|
|
131
|
-
|
|
132
|
-
detached_watsonx_monitor = WatsonxExternalPromptMonitoring(space_id="your_space_id"
|
|
133
|
-
cpd_creds=cpd_creds)
|
|
134
|
-
"""
|
|
135
|
-
|
|
136
|
-
def __init__(self,
|
|
137
|
-
api_key: str = None,
|
|
138
|
-
space_id: str = None,
|
|
139
|
-
project_id: str = None,
|
|
140
|
-
region: Literal["us-south", "eu-de", "au-syd"] = "us-south",
|
|
141
|
-
cpd_creds: CloudPakforDataCredentials | dict = None,
|
|
142
|
-
) -> None:
|
|
143
|
-
|
|
144
|
-
try:
|
|
145
|
-
import ibm_aigov_facts_client # noqa: F401
|
|
146
|
-
import ibm_cloud_sdk_core.authenticators # noqa: F401
|
|
147
|
-
import ibm_watson_openscale # noqa: F401
|
|
148
|
-
import ibm_watsonx_ai # noqa: F401
|
|
149
|
-
|
|
150
|
-
except ImportError:
|
|
151
|
-
raise ImportError("""ibm-aigov-facts-client, ibm-watson-openscale or ibm-watsonx-ai module not found,
|
|
152
|
-
please install it with `pip install ibm-aigov-facts-client ibm-watson-openscale ibm-watsonx-ai`""")
|
|
153
|
-
|
|
154
|
-
if (not (project_id or space_id)) or (project_id and space_id):
|
|
155
|
-
raise ValueError("`project_id` and `space_id` parameter cannot be set at the same time.")
|
|
156
|
-
|
|
157
|
-
self.space_id = space_id
|
|
158
|
-
self.project_id = project_id
|
|
159
|
-
self.region = region
|
|
160
|
-
self._api_key = api_key
|
|
161
|
-
self._wos_client = None
|
|
162
|
-
|
|
163
|
-
self._container_id = space_id if space_id else project_id
|
|
164
|
-
self._container_type = "space" if space_id else "project"
|
|
165
|
-
self._deployment_stage = "production" if space_id else "development"
|
|
166
|
-
|
|
167
|
-
if cpd_creds:
|
|
168
|
-
self._wos_cpd_creds = _filter_dict(cpd_creds.to_dict(), ["username", "password", "api_key",
|
|
169
|
-
"disable_ssl_verification"], ["url"])
|
|
170
|
-
self._fact_cpd_creds = _filter_dict(cpd_creds.to_dict(), ["username", "password", "api_key",
|
|
171
|
-
"bedrock_url"],["url"])
|
|
172
|
-
self._fact_cpd_creds["service_url"] = self._fact_cpd_creds.pop("url")
|
|
173
|
-
self._wml_cpd_creds = _filter_dict(cpd_creds.to_dict(), ["username", "password", "api_key", "instance_id",
|
|
174
|
-
"version", "bedrock_url"], ["url"])
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def _create_detached_prompt(self, detached_details: dict,
|
|
178
|
-
prompt_template_details: dict,
|
|
179
|
-
detached_asset_details: dict) -> str:
|
|
180
|
-
from ibm_aigov_facts_client import ( # type: ignore
|
|
181
|
-
AIGovFactsClient,
|
|
182
|
-
CloudPakforDataConfig,
|
|
183
|
-
DetachedPromptTemplate,
|
|
184
|
-
PromptTemplate,
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
try:
|
|
188
|
-
if hasattr(self, '_fact_cpd_creds') and self._fact_cpd_creds:
|
|
189
|
-
cpd_creds = CloudPakforDataConfig(**self._fact_cpd_creds)
|
|
190
|
-
|
|
191
|
-
aigov_client = AIGovFactsClient(
|
|
192
|
-
container_id=self._container_id,
|
|
193
|
-
container_type=self._container_type,
|
|
194
|
-
cloud_pak_for_data_configs=cpd_creds,
|
|
195
|
-
disable_tracing=True)
|
|
196
|
-
|
|
197
|
-
else:
|
|
198
|
-
aigov_client = AIGovFactsClient(
|
|
199
|
-
api_key=self._api_key,
|
|
200
|
-
container_id=self._container_id,
|
|
201
|
-
container_type=self._container_type,
|
|
202
|
-
disable_tracing=True,
|
|
203
|
-
region=REGIONS_URL[self.region]["factsheet"])
|
|
204
|
-
|
|
205
|
-
except Exception as e:
|
|
206
|
-
logging.error(f"Error connecting to IBM watsonx.governance (factsheets): {e}")
|
|
207
|
-
raise
|
|
208
|
-
|
|
209
|
-
created_detached_pta = aigov_client.assets.create_detached_prompt(
|
|
210
|
-
**detached_asset_details,
|
|
211
|
-
prompt_details=PromptTemplate(**prompt_template_details),
|
|
212
|
-
detached_information=DetachedPromptTemplate(**detached_details))
|
|
213
|
-
|
|
214
|
-
return created_detached_pta.to_dict()["asset_id"]
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def _create_deployment_pta(self, asset_id: str,
|
|
218
|
-
name: str,
|
|
219
|
-
model_id: str) -> str:
|
|
220
|
-
from ibm_watsonx_ai import APIClient, Credentials # type: ignore
|
|
221
|
-
|
|
222
|
-
try:
|
|
223
|
-
if hasattr(self, '_wml_cpd_creds') and self._wml_cpd_creds:
|
|
224
|
-
creds = Credentials(**self._wml_cpd_creds)
|
|
225
|
-
|
|
226
|
-
wml_client = APIClient(creds)
|
|
227
|
-
wml_client.set.default_space(self.space_id)
|
|
228
|
-
|
|
229
|
-
else:
|
|
230
|
-
creds = Credentials(url= REGIONS_URL[self.region]["wml"], api_key=self._api_key)
|
|
231
|
-
wml_client = APIClient(creds)
|
|
232
|
-
wml_client.set.default_space(self.space_id)
|
|
233
|
-
|
|
234
|
-
except Exception as e:
|
|
235
|
-
logging.error(f"Error connecting to IBM watsonx.ai Runtime: {e}")
|
|
236
|
-
raise
|
|
237
|
-
|
|
238
|
-
meta_props = {
|
|
239
|
-
wml_client.deployments.ConfigurationMetaNames.PROMPT_TEMPLATE: { "id" : asset_id },
|
|
240
|
-
wml_client.deployments.ConfigurationMetaNames.DETACHED: {},
|
|
241
|
-
wml_client.deployments.ConfigurationMetaNames.NAME: name + " " + "deployment",
|
|
242
|
-
wml_client.deployments.ConfigurationMetaNames.BASE_MODEL_ID: model_id
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
created_deployment = wml_client.deployments.create(asset_id, meta_props)
|
|
246
|
-
|
|
247
|
-
return wml_client.deployments.get_uid(created_deployment)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
def create_prompt_monitor(self,
|
|
251
|
-
name: str,
|
|
252
|
-
model_id: str,
|
|
253
|
-
task_id: Literal["retrieval_augmented_generation", "summarization"],
|
|
254
|
-
detached_model_provider: str,
|
|
255
|
-
description: str = "",
|
|
256
|
-
model_parameters: dict = None,
|
|
257
|
-
detached_model_name: str = None,
|
|
258
|
-
detached_model_url: str = None,
|
|
259
|
-
detached_prompt_url: str = None,
|
|
260
|
-
detached_prompt_additional_info: dict = None,
|
|
261
|
-
prompt_variables: List[str] = None,
|
|
262
|
-
prompt_template_version: str = None,
|
|
263
|
-
prompt_instruction: str = None,
|
|
264
|
-
input_text: str = None,
|
|
265
|
-
input_prefix: str = None,
|
|
266
|
-
output_prefix: str = None,
|
|
267
|
-
context_fields: List[str] = None,
|
|
268
|
-
question_field: str = None) -> dict:
|
|
269
|
-
"""Create a Detached/External Prompt Template Asset and setup monitors for a given prompt template asset.
|
|
270
|
-
|
|
271
|
-
Args:
|
|
272
|
-
name (str): The name of the External Prompt Template Asset..
|
|
273
|
-
model_id (str): Id of the model associated with the prompt.
|
|
274
|
-
task_id (str): The task identifier. Currently supports "retrieval_augmented_generation" and "summarization" tasks.
|
|
275
|
-
detached_model_provider (str): The external model provider.
|
|
276
|
-
description (str, optional): Description of the External Prompt Template Asset.
|
|
277
|
-
model_parameters (dict, optional): Model parameters and their respective values.
|
|
278
|
-
detached_model_name (str, optional): The name of the external model.
|
|
279
|
-
detached_model_url (str, optional): URL of the external model.
|
|
280
|
-
detached_prompt_url (str, optional): URL of the external prompt.
|
|
281
|
-
detached_prompt_additional_info (dict, optional): Additional information related to the external prompt.
|
|
282
|
-
prompt_variables (List[str], optional): Values for prompt variables.
|
|
283
|
-
prompt_template_version (str, optional): Semantic version of the External Prompt Template Asset.
|
|
284
|
-
prompt_instruction (str, optional): Instruction for using the prompt.
|
|
285
|
-
input_text (str, optional): The input text for the prompt.
|
|
286
|
-
input_prefix (str, optional): A prefix to add to the input.
|
|
287
|
-
output_prefix (str, optional): A prefix to add to the output.
|
|
288
|
-
context_fields (List[str], optional): A list of fields that will provide context to the prompt. Applicable only for ``retrieval_augmented_generation`` problem type.
|
|
289
|
-
question_field (str, optional): The field containing the question to be answered. Applicable only for ``retrieval_augmented_generation`` problem type.
|
|
290
|
-
|
|
291
|
-
**Example**
|
|
292
|
-
|
|
293
|
-
.. code-block:: python
|
|
294
|
-
|
|
295
|
-
detached_watsonx_monitor.create_prompt_monitor(name="Detached prompt (model AWS Anthropic)",
|
|
296
|
-
model_id="anthropic.claude-v2",
|
|
297
|
-
task_id="retrieval_augmented_generation",
|
|
298
|
-
detached_model_provider="AWS Bedrock",
|
|
299
|
-
detached_model_name="Anthropic Claude 2.0",
|
|
300
|
-
detached_model_url="https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-claude.html",
|
|
301
|
-
prompt_variables=["context1", "context2", "input_query"],
|
|
302
|
-
input_text="Prompt text to be given",
|
|
303
|
-
context_fields=["context1", "context2"],
|
|
304
|
-
question_field="input_query")
|
|
305
|
-
|
|
306
|
-
"""
|
|
307
|
-
prompt_metadata = locals()
|
|
308
|
-
# remove unused vars from dict
|
|
309
|
-
prompt_metadata.pop("self", None)
|
|
310
|
-
prompt_metadata.pop("context_fields", None)
|
|
311
|
-
prompt_metadata.pop("question_field", None)
|
|
312
|
-
|
|
313
|
-
# update name of keys to aigov_facts api
|
|
314
|
-
prompt_metadata["model_version"] = prompt_metadata.pop("prompt_template_version", None)
|
|
315
|
-
prompt_metadata["input"] = prompt_metadata.pop("input_text", None)
|
|
316
|
-
prompt_metadata["model_provider"] = prompt_metadata.pop("detached_model_provider", None)
|
|
317
|
-
prompt_metadata["model_name"] = prompt_metadata.pop("detached_model_name", None)
|
|
318
|
-
prompt_metadata["model_url"] = prompt_metadata.pop("detached_model_url", None)
|
|
319
|
-
prompt_metadata["prompt_url"] = prompt_metadata.pop("detached_prompt_url", None)
|
|
320
|
-
prompt_metadata["prompt_additional_info"] = prompt_metadata.pop("detached_prompt_additional_info", None)
|
|
321
|
-
|
|
322
|
-
# update list of vars to dict
|
|
323
|
-
prompt_metadata["prompt_variables"] = { prompt_var: "" for prompt_var in prompt_metadata["prompt_variables"] }
|
|
324
|
-
|
|
325
|
-
from ibm_watson_openscale import APIClient as WosAPIClient # type: ignore
|
|
326
|
-
|
|
327
|
-
if not self._wos_client:
|
|
328
|
-
try:
|
|
329
|
-
if hasattr(self, '_wos_cpd_creds') and self._wos_cpd_creds:
|
|
330
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
331
|
-
CloudPakForDataAuthenticator, # type: ignore
|
|
332
|
-
)
|
|
333
|
-
|
|
334
|
-
authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
|
|
335
|
-
self._wos_client = WosAPIClient(authenticator=authenticator,
|
|
336
|
-
service_url=self._wos_cpd_creds["url"])
|
|
337
|
-
|
|
338
|
-
else:
|
|
339
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
340
|
-
IAMAuthenticator, # type: ignore
|
|
341
|
-
)
|
|
342
|
-
|
|
343
|
-
authenticator = IAMAuthenticator(apikey=self._api_key)
|
|
344
|
-
self._wos_client = WosAPIClient(authenticator=authenticator, service_url=REGIONS_URL[self.region]["wos"])
|
|
345
|
-
|
|
346
|
-
except Exception as e:
|
|
347
|
-
logging.error(f"Error connecting to IBM watsonx.governance (openscale): {e}")
|
|
348
|
-
raise
|
|
349
|
-
|
|
350
|
-
detached_details = _filter_dict(prompt_metadata,
|
|
351
|
-
["model_name", "model_url", "prompt_url", "prompt_additional_info"],
|
|
352
|
-
["model_id", "model_provider"])
|
|
353
|
-
detached_details["prompt_id"] = "detached_prompt_" + str(uuid.uuid4())
|
|
354
|
-
|
|
355
|
-
prompt_details = _filter_dict(prompt_metadata,
|
|
356
|
-
["model_version", "prompt_variables", "prompt_instruction",
|
|
357
|
-
"input_prefix", "output_prefix", "input", "model_parameters"])
|
|
358
|
-
|
|
359
|
-
detached_asset_details = _filter_dict(prompt_metadata, ["description"],
|
|
360
|
-
["name", "model_id", "task_id"])
|
|
361
|
-
|
|
362
|
-
detached_pta_id = self._create_detached_prompt(detached_details, prompt_details, detached_asset_details)
|
|
363
|
-
deployment_id = None
|
|
364
|
-
if self._container_type == "space":
|
|
365
|
-
deployment_id = self._create_deployment_pta(detached_pta_id, name, model_id)
|
|
366
|
-
|
|
367
|
-
monitors = {
|
|
368
|
-
"generative_ai_quality": {
|
|
369
|
-
"parameters": {
|
|
370
|
-
"min_sample_size": 10,
|
|
371
|
-
"metrics_configuration":{}
|
|
372
|
-
}
|
|
373
|
-
}}
|
|
374
|
-
|
|
375
|
-
max_attempt_execute_prompt_setup = 0
|
|
376
|
-
while max_attempt_execute_prompt_setup < 2:
|
|
377
|
-
try:
|
|
378
|
-
generative_ai_monitor_details = self._wos_client.wos.execute_prompt_setup(
|
|
379
|
-
prompt_template_asset_id = detached_pta_id,
|
|
380
|
-
space_id = self.space_id,
|
|
381
|
-
project_id=self.project_id,
|
|
382
|
-
deployment_id = deployment_id,
|
|
383
|
-
label_column = "reference_output",
|
|
384
|
-
context_fields=context_fields,
|
|
385
|
-
question_field = question_field,
|
|
386
|
-
operational_space_id = self._deployment_stage,
|
|
387
|
-
problem_type = task_id,
|
|
388
|
-
input_data_type = "unstructured_text",
|
|
389
|
-
supporting_monitors = monitors,
|
|
390
|
-
background_mode = False).result
|
|
391
|
-
|
|
392
|
-
break
|
|
393
|
-
|
|
394
|
-
except Exception as e:
|
|
395
|
-
if e.code == 403 and "The user entitlement does not exist" in e.message \
|
|
396
|
-
and max_attempt_execute_prompt_setup < 1:
|
|
397
|
-
max_attempt_execute_prompt_setup = max_attempt_execute_prompt_setup + 1
|
|
398
|
-
|
|
399
|
-
data_marts = self._wos_client.data_marts.list().result
|
|
400
|
-
if (data_marts.data_marts is None) or (not data_marts.data_marts):
|
|
401
|
-
raise ValueError("Error retrieving IBM watsonx.governance (openscale) data mart. \
|
|
402
|
-
Make sure the data mart are configured.")
|
|
403
|
-
|
|
404
|
-
data_mart_id = data_marts.data_marts[0].metadata.id
|
|
405
|
-
|
|
406
|
-
self._wos_client.wos.add_instance_mapping(
|
|
407
|
-
service_instance_id=data_mart_id,
|
|
408
|
-
space_id=self.space_id,
|
|
409
|
-
project_id=self.project_id)
|
|
410
|
-
else:
|
|
411
|
-
max_attempt_execute_prompt_setup = 2
|
|
412
|
-
raise e
|
|
413
|
-
|
|
414
|
-
generative_ai_monitor_details = generative_ai_monitor_details._to_dict()
|
|
415
|
-
|
|
416
|
-
return {"detached_prompt_template_asset_id": detached_pta_id,
|
|
417
|
-
"deployment_id": deployment_id,
|
|
418
|
-
"subscription_id": generative_ai_monitor_details["subscription_id"]}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
def payload_logging(self, payload_records: List[dict], subscription_id: str) -> None:
|
|
422
|
-
"""Store records to payload logging.
|
|
423
|
-
|
|
424
|
-
Args:
|
|
425
|
-
payload_records (List[dict]):
|
|
426
|
-
subscription_id (str):
|
|
427
|
-
|
|
428
|
-
**Example**
|
|
429
|
-
|
|
430
|
-
.. code-block:: python
|
|
431
|
-
|
|
432
|
-
detached_watsonx_monitor.payload_logging(payload_records=[{"context1": "value_context1",
|
|
433
|
-
"context2": "value_context1",
|
|
434
|
-
"input_query": "What's Beekeeper?",
|
|
435
|
-
"input_token_count": 25,
|
|
436
|
-
"generated_token_count": 150}],
|
|
437
|
-
subscription_id="5d62977c-a53d-4b6d-bda1-7b79b3b9d1a0")
|
|
438
|
-
"""
|
|
439
|
-
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
|
|
440
|
-
from ibm_watson_openscale import APIClient as WosAPIClient
|
|
441
|
-
from ibm_watson_openscale.supporting_classes.enums import (
|
|
442
|
-
DataSetTypes,
|
|
443
|
-
TargetTypes,
|
|
444
|
-
)
|
|
445
|
-
|
|
446
|
-
if not self._wos_client:
|
|
447
|
-
try:
|
|
448
|
-
if hasattr(self, '_wos_cpd_creds') and self._wos_cpd_creds:
|
|
449
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
450
|
-
CloudPakForDataAuthenticator, # type: ignore
|
|
451
|
-
)
|
|
452
|
-
|
|
453
|
-
authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
|
|
454
|
-
self._wos_client = WosAPIClient(authenticator=authenticator,
|
|
455
|
-
service_url=self._wos_cpd_creds["url"])
|
|
456
|
-
|
|
457
|
-
else:
|
|
458
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
459
|
-
IAMAuthenticator, # type: ignore
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
authenticator = IAMAuthenticator(apikey=self._api_key)
|
|
463
|
-
self._wos_client = WosAPIClient(authenticator=authenticator, service_url=REGIONS_URL[self.region]["wos"])
|
|
464
|
-
|
|
465
|
-
except Exception as e:
|
|
466
|
-
logging.error(f"Error connecting to IBM watsonx.governance (openscale): {e}")
|
|
467
|
-
raise
|
|
468
|
-
|
|
469
|
-
subscription_details = self._wos_client.subscriptions.get(subscription_id).result
|
|
470
|
-
subscription_details = json.loads(str(subscription_details))
|
|
471
|
-
|
|
472
|
-
feature_fields = subscription_details["entity"]["asset_properties"]["feature_fields"]
|
|
473
|
-
|
|
474
|
-
payload_data_set_id = self._wos_client.data_sets.list(type=DataSetTypes.PAYLOAD_LOGGING,
|
|
475
|
-
target_target_id=subscription_id,
|
|
476
|
-
target_target_type=TargetTypes.SUBSCRIPTION).result.data_sets[0].metadata.id
|
|
477
|
-
|
|
478
|
-
payload_data = _convert_payload_format(payload_records, feature_fields)
|
|
479
|
-
self._wos_client.data_sets.store_records(data_set_id=payload_data_set_id,
|
|
480
|
-
request_body=payload_data,
|
|
481
|
-
background_mode=False)
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
class WatsonxPromptMonitoring:
|
|
485
|
-
"""Provides functionality to interact with IBM watsonx.governance for monitoring IBM watsonx.ai LLM's.
|
|
486
|
-
|
|
487
|
-
Note:
|
|
488
|
-
One of these parameters is required to create prompt monitor: ``project_id`` or ``space_id``. Not both.
|
|
489
|
-
|
|
490
|
-
Args:
|
|
491
|
-
api_key (str): IBM watsonx.governance API key.
|
|
492
|
-
space_id (str, optional): watsonx.governance space_id.
|
|
493
|
-
project_id (str, optional): watsonx.governance project_id.
|
|
494
|
-
region (str, optional): Region where the watsonx.governance is hosted when using IBM Cloud. Defaults to ``us-south``
|
|
495
|
-
cpd_creds (CloudPakforDataCredentials, optional): Cloud Pak for Data environment details.
|
|
496
|
-
|
|
497
|
-
**Example**
|
|
498
|
-
|
|
499
|
-
.. code-block:: python
|
|
500
|
-
|
|
501
|
-
from beekeeper.monitor import WatsonxPromptMonitoring
|
|
502
|
-
|
|
503
|
-
# watsonx.governance (IBM Cloud)
|
|
504
|
-
watsonx_monitor = WatsonxExternalPromptMonitoring(api_key="your_api_key",
|
|
505
|
-
space_id="your_space_id")
|
|
506
|
-
|
|
507
|
-
# watsonx.governance (cp4d)
|
|
508
|
-
from beekeeper.monitor import CloudPakforDataCredentials
|
|
509
|
-
|
|
510
|
-
cpd_creds = CloudPakforDataCredentials(url="your_cpd_url",
|
|
511
|
-
username="your_username", password="your_password",
|
|
512
|
-
version="5.0", instance_id="openshift")
|
|
513
|
-
|
|
514
|
-
detached_watsonx_monitor = WatsonxExternalPromptMonitoring(space_id="your_space_id"
|
|
515
|
-
cpd_creds=cpd_creds)
|
|
516
|
-
"""
|
|
517
|
-
|
|
518
|
-
def __init__(self,
|
|
519
|
-
api_key: str =None,
|
|
520
|
-
space_id: str = None,
|
|
521
|
-
project_id: str = None,
|
|
522
|
-
region: Literal["us-south", "eu-de", "au-syd"] = "us-south",
|
|
523
|
-
cpd_creds: CloudPakforDataCredentials | dict = None,
|
|
524
|
-
) -> None:
|
|
525
|
-
try:
|
|
526
|
-
import ibm_aigov_facts_client # noqa: F401
|
|
527
|
-
import ibm_cloud_sdk_core.authenticators # noqa: F401
|
|
528
|
-
import ibm_watson_openscale # noqa: F401
|
|
529
|
-
import ibm_watsonx_ai # noqa: F401
|
|
530
|
-
|
|
531
|
-
except ImportError:
|
|
532
|
-
raise ImportError("""ibm-aigov-facts-client, ibm-watson-openscale or ibm-watsonx-ai module not found,
|
|
533
|
-
please install it with `pip install ibm-aigov-facts-client ibm-watson-openscale ibm-watsonx-ai`""")
|
|
534
|
-
|
|
535
|
-
if (not (project_id or space_id)) or (project_id and space_id):
|
|
536
|
-
raise ValueError("`project_id` and `space_id` parameter cannot be set at the same time.")
|
|
537
|
-
|
|
538
|
-
self.space_id = space_id
|
|
539
|
-
self.project_id = project_id
|
|
540
|
-
self.region = region
|
|
541
|
-
self._api_key = api_key
|
|
542
|
-
self._wos_client = None
|
|
543
|
-
|
|
544
|
-
self._container_id = space_id if space_id else project_id
|
|
545
|
-
self._container_type = "space" if space_id else "project"
|
|
546
|
-
self._deployment_stage = "production" if space_id else "development"
|
|
547
|
-
|
|
548
|
-
if cpd_creds:
|
|
549
|
-
self._wos_cpd_creds = _filter_dict(cpd_creds.to_dict(), ["username", "password", "api_key",
|
|
550
|
-
"disable_ssl_verification"], ["url"])
|
|
551
|
-
self._fact_cpd_creds = _filter_dict(cpd_creds.to_dict(), ["username", "password", "api_key",
|
|
552
|
-
"bedrock_url"],["url"])
|
|
553
|
-
self._fact_cpd_creds["service_url"] = self._fact_cpd_creds.pop("url")
|
|
554
|
-
self._wml_cpd_creds = _filter_dict(cpd_creds.to_dict(), ["username", "password", "api_key", "instance_id",
|
|
555
|
-
"version", "bedrock_url"], ["url"])
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
def _create_prompt_template(self, prompt_template_details: dict, asset_details: dict) -> str:
|
|
559
|
-
from ibm_aigov_facts_client import (
|
|
560
|
-
AIGovFactsClient,
|
|
561
|
-
CloudPakforDataConfig,
|
|
562
|
-
PromptTemplate,
|
|
563
|
-
)
|
|
564
|
-
|
|
565
|
-
try:
|
|
566
|
-
if hasattr(self, '_fact_cpd_creds') and self._fact_cpd_creds:
|
|
567
|
-
cpd_creds = CloudPakforDataConfig(**self._fact_cpd_creds)
|
|
568
|
-
|
|
569
|
-
aigov_client = AIGovFactsClient(
|
|
570
|
-
container_id=self._container_id,
|
|
571
|
-
container_type=self._container_type,
|
|
572
|
-
cloud_pak_for_data_configs=cpd_creds,
|
|
573
|
-
disable_tracing=True)
|
|
574
|
-
|
|
575
|
-
else:
|
|
576
|
-
aigov_client = AIGovFactsClient(
|
|
577
|
-
api_key=self._api_key,
|
|
578
|
-
container_id=self._container_id,
|
|
579
|
-
container_type=self._container_type,
|
|
580
|
-
disable_tracing=True,
|
|
581
|
-
region=REGIONS_URL[self.region]["factsheet"])
|
|
582
|
-
|
|
583
|
-
except Exception as e:
|
|
584
|
-
logging.error(f"Error connecting to IBM watsonx.governance (factsheets): {e}")
|
|
585
|
-
raise
|
|
586
|
-
|
|
587
|
-
created_pta = aigov_client.assets.create_prompt(
|
|
588
|
-
**asset_details,
|
|
589
|
-
input_mode="structured",
|
|
590
|
-
prompt_details=PromptTemplate(**prompt_template_details))
|
|
591
|
-
|
|
592
|
-
return created_pta.to_dict()["asset_id"]
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
def _create_deployment_pta(self, asset_id: str,
|
|
596
|
-
name: str,
|
|
597
|
-
model_id: str) -> str:
|
|
598
|
-
from ibm_watsonx_ai import APIClient, Credentials # type: ignore
|
|
599
|
-
|
|
600
|
-
try:
|
|
601
|
-
if hasattr(self, '_wml_cpd_creds') and self._wml_cpd_creds:
|
|
602
|
-
creds = Credentials(**self._wml_cpd_creds)
|
|
603
|
-
|
|
604
|
-
wml_client = APIClient(creds)
|
|
605
|
-
wml_client.set.default_space(self.space_id)
|
|
606
|
-
|
|
607
|
-
else:
|
|
608
|
-
creds = Credentials(url= REGIONS_URL[self.region]["wml"], api_key=self._api_key)
|
|
609
|
-
|
|
610
|
-
wml_client = APIClient(creds)
|
|
611
|
-
wml_client.set.default_space(self.space_id)
|
|
612
|
-
|
|
613
|
-
except Exception as e:
|
|
614
|
-
logging.error(f"Error connecting to IBM watsonx.ai Runtime: {e}")
|
|
615
|
-
raise
|
|
616
|
-
|
|
617
|
-
meta_props = {
|
|
618
|
-
wml_client.deployments.ConfigurationMetaNames.PROMPT_TEMPLATE: { "id" : asset_id },
|
|
619
|
-
wml_client.deployments.ConfigurationMetaNames.FOUNDATION_MODEL: {},
|
|
620
|
-
wml_client.deployments.ConfigurationMetaNames.NAME: name + " " + "deployment",
|
|
621
|
-
wml_client.deployments.ConfigurationMetaNames.BASE_MODEL_ID: model_id
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
created_deployment = wml_client.deployments.create(asset_id, meta_props)
|
|
625
|
-
|
|
626
|
-
return wml_client.deployments.get_uid(created_deployment)
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
def create_prompt_monitor(self,
|
|
630
|
-
name: str,
|
|
631
|
-
model_id: str,
|
|
632
|
-
task_id: Literal["retrieval_augmented_generation", "summarization"],
|
|
633
|
-
description: str = "",
|
|
634
|
-
model_parameters: dict = None,
|
|
635
|
-
prompt_variables: List[str] = None,
|
|
636
|
-
prompt_template_version: str = None,
|
|
637
|
-
prompt_instruction: str = None,
|
|
638
|
-
input_text: str = None,
|
|
639
|
-
input_prefix: str = None,
|
|
640
|
-
output_prefix: str = None,
|
|
641
|
-
context_fields: List[str] = None,
|
|
642
|
-
question_field: str = None,
|
|
643
|
-
) -> dict:
|
|
644
|
-
"""Create an IBM Prompt Template Asset and setup monitors for a given prompt template asset.
|
|
645
|
-
|
|
646
|
-
Args:
|
|
647
|
-
name (str): The name of the Prompt Template Asset.
|
|
648
|
-
model_id (str): Id of the model associated with the prompt.
|
|
649
|
-
task_id (str): The task identifier. Currently supports "retrieval_augmented_generation" and "summarization" tasks.
|
|
650
|
-
description (str, optional): Description of the Prompt Template Asset.
|
|
651
|
-
model_parameters (dict, optional): Model parameters and their respective values.
|
|
652
|
-
prompt_variables (List[str], optional): Values for prompt input variables.
|
|
653
|
-
prompt_template_version (str, optional): Semantic version of the Prompt Template Asset.
|
|
654
|
-
prompt_instruction (str, optional): Instruction for using the prompt.
|
|
655
|
-
input_text (str, optional): The input text for the prompt.
|
|
656
|
-
input_prefix (str, optional): A prefix to add to the input.
|
|
657
|
-
output_prefix (str, optional): A prefix to add to the output.
|
|
658
|
-
context_fields (List[str], optional): A list of fields that will provide context to the prompt. Applicable only for ``retrieval_augmented_generation`` problem type.
|
|
659
|
-
question_field (str, optional): The field containing the question to be answered. Applicable only for ``retrieval_augmented_generation`` problem type.
|
|
660
|
-
|
|
661
|
-
**Example**
|
|
662
|
-
|
|
663
|
-
.. code-block:: python
|
|
664
|
-
|
|
665
|
-
watsonx_monitor.create_prompt_monitor(name="IBM prompt template",
|
|
666
|
-
model_id="ibm/granite-3-2b-instruct",
|
|
667
|
-
task_id="retrieval_augmented_generation",
|
|
668
|
-
prompt_variables=["context1", "context2", "input_query"],
|
|
669
|
-
input_text="Prompt text to be given",
|
|
670
|
-
context_fields=["context1", "context2"],
|
|
671
|
-
question_field="input_query")
|
|
672
|
-
|
|
673
|
-
"""
|
|
674
|
-
prompt_metadata = locals()
|
|
675
|
-
# remove unused vars from dict
|
|
676
|
-
prompt_metadata.pop("self", None)
|
|
677
|
-
prompt_metadata.pop("context_fields", None)
|
|
678
|
-
prompt_metadata.pop("question_field", None)
|
|
679
|
-
|
|
680
|
-
# update name of keys to aigov_facts api
|
|
681
|
-
prompt_metadata["model_version"] = prompt_metadata.pop("prompt_template_version", None)
|
|
682
|
-
prompt_metadata["input"] = prompt_metadata.pop("input_text", None)
|
|
683
|
-
|
|
684
|
-
# update list of vars to dict
|
|
685
|
-
prompt_metadata["prompt_variables"] = { prompt_var: "" for prompt_var in prompt_metadata["prompt_variables"] }
|
|
686
|
-
|
|
687
|
-
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator # type: ignore
|
|
688
|
-
from ibm_watson_openscale import APIClient as WosAPIClient # type: ignore
|
|
689
|
-
|
|
690
|
-
if not self._wos_client:
|
|
691
|
-
try:
|
|
692
|
-
if hasattr(self, '_wos_cpd_creds') and self._wos_cpd_creds:
|
|
693
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
694
|
-
CloudPakForDataAuthenticator, # type: ignore
|
|
695
|
-
)
|
|
696
|
-
|
|
697
|
-
authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
|
|
698
|
-
|
|
699
|
-
self._wos_client = WosAPIClient(authenticator=authenticator,
|
|
700
|
-
service_url=self._wos_cpd_creds["url"])
|
|
701
|
-
|
|
702
|
-
else:
|
|
703
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
704
|
-
IAMAuthenticator, # type: ignore
|
|
705
|
-
)
|
|
706
|
-
|
|
707
|
-
authenticator = IAMAuthenticator(apikey=self._api_key)
|
|
708
|
-
self._wos_client = WosAPIClient(authenticator=authenticator, service_url=REGIONS_URL[self.region]["wos"])
|
|
709
|
-
|
|
710
|
-
except Exception as e:
|
|
711
|
-
logging.error(f"Error connecting to IBM watsonx.governance (openscale): {e}")
|
|
712
|
-
raise
|
|
713
|
-
|
|
714
|
-
prompt_details = _filter_dict(prompt_metadata,
|
|
715
|
-
["model_version", "prompt_variables", "prompt_instruction",
|
|
716
|
-
"input_prefix", "output_prefix", "input", "model_parameters"])
|
|
717
|
-
|
|
718
|
-
asset_details = _filter_dict(prompt_metadata, ["description"],
|
|
719
|
-
["name", "model_id", "task_id"])
|
|
720
|
-
|
|
721
|
-
pta_id = self._create_prompt_template(prompt_details, asset_details)
|
|
722
|
-
deployment_id = None
|
|
723
|
-
if self._container_type == "space":
|
|
724
|
-
deployment_id = self._create_deployment_pta(pta_id, name, model_id)
|
|
725
|
-
|
|
726
|
-
monitors = {
|
|
727
|
-
"generative_ai_quality": {
|
|
728
|
-
"parameters": {
|
|
729
|
-
"min_sample_size": 10,
|
|
730
|
-
"metrics_configuration":{}
|
|
731
|
-
}
|
|
732
|
-
}}
|
|
733
|
-
|
|
734
|
-
max_attempt_execute_prompt_setup = 0
|
|
735
|
-
while max_attempt_execute_prompt_setup < 2:
|
|
736
|
-
try:
|
|
737
|
-
generative_ai_monitor_details = self._wos_client.wos.execute_prompt_setup(
|
|
738
|
-
prompt_template_asset_id = pta_id,
|
|
739
|
-
space_id = self.space_id,
|
|
740
|
-
project_id=self.project_id,
|
|
741
|
-
deployment_id = deployment_id,
|
|
742
|
-
label_column = "reference_output",
|
|
743
|
-
context_fields=context_fields,
|
|
744
|
-
question_field = question_field,
|
|
745
|
-
operational_space_id = self._deployment_stage,
|
|
746
|
-
problem_type = task_id,
|
|
747
|
-
input_data_type = "unstructured_text",
|
|
748
|
-
supporting_monitors = monitors,
|
|
749
|
-
background_mode = False).result
|
|
750
|
-
|
|
751
|
-
break
|
|
752
|
-
|
|
753
|
-
except Exception as e:
|
|
754
|
-
if e.code == 403 and "The user entitlement does not exist" in e.message \
|
|
755
|
-
and max_attempt_execute_prompt_setup < 1:
|
|
756
|
-
max_attempt_execute_prompt_setup = max_attempt_execute_prompt_setup + 1
|
|
757
|
-
|
|
758
|
-
data_marts = self._wos_client.data_marts.list().result
|
|
759
|
-
if (data_marts.data_marts is None) or (not data_marts.data_marts):
|
|
760
|
-
raise ValueError("Error retrieving IBM watsonx.governance (openscale) data mart. \
|
|
761
|
-
Make sure the data mart are configured.")
|
|
762
|
-
|
|
763
|
-
data_mart_id = data_marts.data_marts[0].metadata.id
|
|
764
|
-
|
|
765
|
-
self._wos_client.wos.add_instance_mapping(
|
|
766
|
-
service_instance_id=data_mart_id,
|
|
767
|
-
space_id=self.space_id,
|
|
768
|
-
project_id=self.project_id)
|
|
769
|
-
else:
|
|
770
|
-
max_attempt_execute_prompt_setup = 2
|
|
771
|
-
raise e
|
|
772
|
-
|
|
773
|
-
generative_ai_monitor_details = generative_ai_monitor_details._to_dict()
|
|
774
|
-
|
|
775
|
-
return {"prompt_template_asset_id": pta_id,
|
|
776
|
-
"deployment_id": deployment_id,
|
|
777
|
-
"subscription_id": generative_ai_monitor_details["subscription_id"]}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
def payload_logging(self, payload_records: List[dict], subscription_id: str) -> None:
|
|
781
|
-
"""Store records to payload logging.
|
|
782
|
-
|
|
783
|
-
Args:
|
|
784
|
-
payload_records (List[dict]):
|
|
785
|
-
subscription_id (str):
|
|
786
|
-
|
|
787
|
-
**Example**
|
|
788
|
-
|
|
789
|
-
.. code-block:: python
|
|
790
|
-
|
|
791
|
-
watsonx_monitor.payload_logging(payload_records=[{"context1": "value_context1",
|
|
792
|
-
"context2": "value_context1",
|
|
793
|
-
"input_query": "What's Beekeeper?",
|
|
794
|
-
"input_token_count": 25,
|
|
795
|
-
"generated_token_count": 150}],
|
|
796
|
-
subscription_id="5d62977c-a53d-4b6d-bda1-7b79b3b9d1a0")
|
|
797
|
-
"""
|
|
798
|
-
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
|
|
799
|
-
from ibm_watson_openscale import APIClient as WosAPIClient
|
|
800
|
-
from ibm_watson_openscale.supporting_classes.enums import (
|
|
801
|
-
DataSetTypes,
|
|
802
|
-
TargetTypes,
|
|
803
|
-
)
|
|
804
|
-
|
|
805
|
-
if not self._wos_client:
|
|
806
|
-
try:
|
|
807
|
-
if hasattr(self, '_wos_cpd_creds') and self._wos_cpd_creds:
|
|
808
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
809
|
-
CloudPakForDataAuthenticator, # type: ignore
|
|
810
|
-
)
|
|
811
|
-
|
|
812
|
-
authenticator = CloudPakForDataAuthenticator(**self._wos_cpd_creds)
|
|
813
|
-
|
|
814
|
-
self._wos_client = WosAPIClient(authenticator=authenticator,
|
|
815
|
-
service_url=self._wos_cpd_creds["url"])
|
|
816
|
-
|
|
817
|
-
else:
|
|
818
|
-
from ibm_cloud_sdk_core.authenticators import (
|
|
819
|
-
IAMAuthenticator, # type: ignore
|
|
820
|
-
)
|
|
821
|
-
|
|
822
|
-
authenticator = IAMAuthenticator(apikey=self._api_key)
|
|
823
|
-
self._wos_client = WosAPIClient(authenticator=authenticator, service_url=REGIONS_URL[self.region]["wos"])
|
|
824
|
-
|
|
825
|
-
except Exception as e:
|
|
826
|
-
logging.error(f"Error connecting to IBM watsonx.governance (openscale): {e}")
|
|
827
|
-
raise
|
|
828
|
-
|
|
829
|
-
subscription_details = self._wos_client.subscriptions.get(subscription_id).result
|
|
830
|
-
subscription_details = json.loads(str(subscription_details))
|
|
831
|
-
|
|
832
|
-
feature_fields = subscription_details["entity"]["asset_properties"]["feature_fields"]
|
|
833
|
-
|
|
834
|
-
payload_data_set_id = self._wos_client.data_sets.list(type=DataSetTypes.PAYLOAD_LOGGING,
|
|
835
|
-
target_target_id=subscription_id,
|
|
836
|
-
target_target_type=TargetTypes.SUBSCRIPTION).result.data_sets[0].metadata.id
|
|
837
|
-
|
|
838
|
-
payload_data = _convert_payload_format(payload_records, feature_fields)
|
|
839
|
-
self._wos_client.data_sets.store_records(data_set_id=payload_data_set_id,
|
|
840
|
-
request_body=payload_data,
|
|
841
|
-
background_mode=False)
|
|
842
|
-
|
|
843
|
-
|