holmesgpt 0.13.2__py3-none-any.whl → 0.18.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.
Files changed (188) hide show
  1. holmes/__init__.py +3 -5
  2. holmes/clients/robusta_client.py +20 -6
  3. holmes/common/env_vars.py +58 -3
  4. holmes/common/openshift.py +1 -1
  5. holmes/config.py +123 -148
  6. holmes/core/conversations.py +71 -15
  7. holmes/core/feedback.py +191 -0
  8. holmes/core/investigation.py +31 -39
  9. holmes/core/investigation_structured_output.py +3 -3
  10. holmes/core/issue.py +1 -1
  11. holmes/core/llm.py +508 -88
  12. holmes/core/models.py +108 -4
  13. holmes/core/openai_formatting.py +14 -1
  14. holmes/core/prompt.py +48 -3
  15. holmes/core/runbooks.py +1 -0
  16. holmes/core/safeguards.py +8 -6
  17. holmes/core/supabase_dal.py +295 -100
  18. holmes/core/tool_calling_llm.py +489 -428
  19. holmes/core/tools.py +325 -56
  20. holmes/core/tools_utils/token_counting.py +21 -0
  21. holmes/core/tools_utils/tool_context_window_limiter.py +40 -0
  22. holmes/core/tools_utils/tool_executor.py +0 -13
  23. holmes/core/tools_utils/toolset_utils.py +1 -0
  24. holmes/core/toolset_manager.py +191 -5
  25. holmes/core/tracing.py +19 -3
  26. holmes/core/transformers/__init__.py +23 -0
  27. holmes/core/transformers/base.py +63 -0
  28. holmes/core/transformers/llm_summarize.py +175 -0
  29. holmes/core/transformers/registry.py +123 -0
  30. holmes/core/transformers/transformer.py +32 -0
  31. holmes/core/truncation/compaction.py +94 -0
  32. holmes/core/truncation/dal_truncation_utils.py +23 -0
  33. holmes/core/truncation/input_context_window_limiter.py +219 -0
  34. holmes/interactive.py +228 -31
  35. holmes/main.py +23 -40
  36. holmes/plugins/interfaces.py +2 -1
  37. holmes/plugins/prompts/__init__.py +2 -1
  38. holmes/plugins/prompts/_fetch_logs.jinja2 +31 -6
  39. holmes/plugins/prompts/_general_instructions.jinja2 +1 -2
  40. holmes/plugins/prompts/_runbook_instructions.jinja2 +24 -12
  41. holmes/plugins/prompts/base_user_prompt.jinja2 +7 -0
  42. holmes/plugins/prompts/conversation_history_compaction.jinja2 +89 -0
  43. holmes/plugins/prompts/generic_ask.jinja2 +0 -4
  44. holmes/plugins/prompts/generic_ask_conversation.jinja2 +0 -1
  45. holmes/plugins/prompts/generic_ask_for_issue_conversation.jinja2 +0 -1
  46. holmes/plugins/prompts/generic_investigation.jinja2 +0 -1
  47. holmes/plugins/prompts/investigation_procedure.jinja2 +50 -1
  48. holmes/plugins/prompts/kubernetes_workload_ask.jinja2 +0 -1
  49. holmes/plugins/prompts/kubernetes_workload_chat.jinja2 +0 -1
  50. holmes/plugins/runbooks/__init__.py +145 -17
  51. holmes/plugins/runbooks/catalog.json +2 -0
  52. holmes/plugins/sources/github/__init__.py +4 -2
  53. holmes/plugins/sources/prometheus/models.py +1 -0
  54. holmes/plugins/toolsets/__init__.py +44 -27
  55. holmes/plugins/toolsets/aks-node-health.yaml +46 -0
  56. holmes/plugins/toolsets/aks.yaml +64 -0
  57. holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +38 -47
  58. holmes/plugins/toolsets/azure_sql/apis/alert_monitoring_api.py +3 -2
  59. holmes/plugins/toolsets/azure_sql/apis/azure_sql_api.py +2 -1
  60. holmes/plugins/toolsets/azure_sql/apis/connection_failure_api.py +3 -2
  61. holmes/plugins/toolsets/azure_sql/apis/connection_monitoring_api.py +3 -1
  62. holmes/plugins/toolsets/azure_sql/apis/storage_analysis_api.py +3 -1
  63. holmes/plugins/toolsets/azure_sql/azure_sql_toolset.py +12 -13
  64. holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +15 -12
  65. holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +15 -12
  66. holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +11 -11
  67. holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +11 -9
  68. holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +15 -12
  69. holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +15 -15
  70. holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +11 -8
  71. holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +11 -8
  72. holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +11 -8
  73. holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +11 -8
  74. holmes/plugins/toolsets/azure_sql/utils.py +0 -32
  75. holmes/plugins/toolsets/bash/argocd/__init__.py +3 -3
  76. holmes/plugins/toolsets/bash/aws/__init__.py +4 -4
  77. holmes/plugins/toolsets/bash/azure/__init__.py +4 -4
  78. holmes/plugins/toolsets/bash/bash_toolset.py +11 -15
  79. holmes/plugins/toolsets/bash/common/bash.py +23 -13
  80. holmes/plugins/toolsets/bash/common/bash_command.py +1 -1
  81. holmes/plugins/toolsets/bash/common/stringify.py +1 -1
  82. holmes/plugins/toolsets/bash/kubectl/__init__.py +2 -1
  83. holmes/plugins/toolsets/bash/kubectl/constants.py +0 -1
  84. holmes/plugins/toolsets/bash/kubectl/kubectl_get.py +3 -4
  85. holmes/plugins/toolsets/bash/parse_command.py +12 -13
  86. holmes/plugins/toolsets/cilium.yaml +284 -0
  87. holmes/plugins/toolsets/connectivity_check.py +124 -0
  88. holmes/plugins/toolsets/coralogix/api.py +132 -119
  89. holmes/plugins/toolsets/coralogix/coralogix.jinja2 +14 -0
  90. holmes/plugins/toolsets/coralogix/toolset_coralogix.py +219 -0
  91. holmes/plugins/toolsets/coralogix/utils.py +15 -79
  92. holmes/plugins/toolsets/datadog/datadog_api.py +525 -26
  93. holmes/plugins/toolsets/datadog/datadog_logs_instructions.jinja2 +55 -11
  94. holmes/plugins/toolsets/datadog/datadog_metrics_instructions.jinja2 +3 -3
  95. holmes/plugins/toolsets/datadog/datadog_models.py +59 -0
  96. holmes/plugins/toolsets/datadog/datadog_url_utils.py +213 -0
  97. holmes/plugins/toolsets/datadog/instructions_datadog_traces.jinja2 +165 -28
  98. holmes/plugins/toolsets/datadog/toolset_datadog_general.py +417 -241
  99. holmes/plugins/toolsets/datadog/toolset_datadog_logs.py +234 -214
  100. holmes/plugins/toolsets/datadog/toolset_datadog_metrics.py +167 -79
  101. holmes/plugins/toolsets/datadog/toolset_datadog_traces.py +374 -363
  102. holmes/plugins/toolsets/elasticsearch/__init__.py +6 -0
  103. holmes/plugins/toolsets/elasticsearch/elasticsearch.py +834 -0
  104. holmes/plugins/toolsets/elasticsearch/opensearch_ppl_query_docs.jinja2 +1616 -0
  105. holmes/plugins/toolsets/elasticsearch/opensearch_query_assist.py +78 -0
  106. holmes/plugins/toolsets/elasticsearch/opensearch_query_assist_instructions.jinja2 +223 -0
  107. holmes/plugins/toolsets/git.py +54 -50
  108. holmes/plugins/toolsets/grafana/base_grafana_toolset.py +16 -4
  109. holmes/plugins/toolsets/grafana/common.py +13 -29
  110. holmes/plugins/toolsets/grafana/grafana_tempo_api.py +455 -0
  111. holmes/plugins/toolsets/grafana/loki/instructions.jinja2 +25 -0
  112. holmes/plugins/toolsets/grafana/loki/toolset_grafana_loki.py +191 -0
  113. holmes/plugins/toolsets/grafana/loki_api.py +4 -0
  114. holmes/plugins/toolsets/grafana/toolset_grafana.py +293 -89
  115. holmes/plugins/toolsets/grafana/toolset_grafana_dashboard.jinja2 +49 -0
  116. holmes/plugins/toolsets/grafana/toolset_grafana_tempo.jinja2 +246 -11
  117. holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +820 -292
  118. holmes/plugins/toolsets/grafana/trace_parser.py +4 -3
  119. holmes/plugins/toolsets/internet/internet.py +15 -16
  120. holmes/plugins/toolsets/internet/notion.py +9 -11
  121. holmes/plugins/toolsets/investigator/core_investigation.py +44 -36
  122. holmes/plugins/toolsets/investigator/model.py +3 -1
  123. holmes/plugins/toolsets/json_filter_mixin.py +134 -0
  124. holmes/plugins/toolsets/kafka.py +36 -42
  125. holmes/plugins/toolsets/kubernetes.yaml +317 -113
  126. holmes/plugins/toolsets/kubernetes_logs.py +9 -9
  127. holmes/plugins/toolsets/kubernetes_logs.yaml +32 -0
  128. holmes/plugins/toolsets/logging_utils/logging_api.py +94 -8
  129. holmes/plugins/toolsets/mcp/toolset_mcp.py +218 -64
  130. holmes/plugins/toolsets/newrelic/new_relic_api.py +165 -0
  131. holmes/plugins/toolsets/newrelic/newrelic.jinja2 +65 -0
  132. holmes/plugins/toolsets/newrelic/newrelic.py +320 -0
  133. holmes/plugins/toolsets/openshift.yaml +283 -0
  134. holmes/plugins/toolsets/prometheus/prometheus.py +1202 -421
  135. holmes/plugins/toolsets/prometheus/prometheus_instructions.jinja2 +54 -5
  136. holmes/plugins/toolsets/prometheus/utils.py +28 -0
  137. holmes/plugins/toolsets/rabbitmq/api.py +23 -4
  138. holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +13 -14
  139. holmes/plugins/toolsets/robusta/robusta.py +239 -68
  140. holmes/plugins/toolsets/robusta/robusta_instructions.jinja2 +26 -9
  141. holmes/plugins/toolsets/runbook/runbook_fetcher.py +157 -27
  142. holmes/plugins/toolsets/service_discovery.py +1 -1
  143. holmes/plugins/toolsets/servicenow_tables/instructions.jinja2 +83 -0
  144. holmes/plugins/toolsets/servicenow_tables/servicenow_tables.py +426 -0
  145. holmes/plugins/toolsets/utils.py +88 -0
  146. holmes/utils/config_utils.py +91 -0
  147. holmes/utils/connection_utils.py +31 -0
  148. holmes/utils/console/result.py +10 -0
  149. holmes/utils/default_toolset_installation_guide.jinja2 +1 -22
  150. holmes/utils/env.py +7 -0
  151. holmes/utils/file_utils.py +2 -1
  152. holmes/utils/global_instructions.py +60 -11
  153. holmes/utils/holmes_status.py +6 -4
  154. holmes/utils/holmes_sync_toolsets.py +0 -2
  155. holmes/utils/krr_utils.py +188 -0
  156. holmes/utils/log.py +15 -0
  157. holmes/utils/markdown_utils.py +2 -3
  158. holmes/utils/memory_limit.py +58 -0
  159. holmes/utils/sentry_helper.py +64 -0
  160. holmes/utils/stream.py +69 -8
  161. holmes/utils/tags.py +4 -3
  162. holmes/version.py +37 -15
  163. holmesgpt-0.18.4.dist-info/LICENSE +178 -0
  164. {holmesgpt-0.13.2.dist-info → holmesgpt-0.18.4.dist-info}/METADATA +35 -31
  165. holmesgpt-0.18.4.dist-info/RECORD +258 -0
  166. holmes/core/performance_timing.py +0 -72
  167. holmes/plugins/toolsets/aws.yaml +0 -80
  168. holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +0 -112
  169. holmes/plugins/toolsets/datadog/datadog_traces_formatter.py +0 -310
  170. holmes/plugins/toolsets/datadog/toolset_datadog_rds.py +0 -739
  171. holmes/plugins/toolsets/grafana/grafana_api.py +0 -42
  172. holmes/plugins/toolsets/grafana/tempo_api.py +0 -124
  173. holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +0 -110
  174. holmes/plugins/toolsets/newrelic.py +0 -231
  175. holmes/plugins/toolsets/opensearch/opensearch.py +0 -257
  176. holmes/plugins/toolsets/opensearch/opensearch_logs.py +0 -161
  177. holmes/plugins/toolsets/opensearch/opensearch_traces.py +0 -218
  178. holmes/plugins/toolsets/opensearch/opensearch_traces_instructions.jinja2 +0 -12
  179. holmes/plugins/toolsets/opensearch/opensearch_utils.py +0 -166
  180. holmes/plugins/toolsets/servicenow/install.md +0 -37
  181. holmes/plugins/toolsets/servicenow/instructions.jinja2 +0 -3
  182. holmes/plugins/toolsets/servicenow/servicenow.py +0 -219
  183. holmes/utils/keygen_utils.py +0 -6
  184. holmesgpt-0.13.2.dist-info/LICENSE.txt +0 -21
  185. holmesgpt-0.13.2.dist-info/RECORD +0 -234
  186. /holmes/plugins/toolsets/{opensearch → newrelic}/__init__.py +0 -0
  187. {holmesgpt-0.13.2.dist-info → holmesgpt-0.18.4.dist-info}/WHEEL +0 -0
  188. {holmesgpt-0.13.2.dist-info → holmesgpt-0.18.4.dist-info}/entry_points.txt +0 -0
@@ -7,6 +7,10 @@ toolsets:
7
7
  - command: "az account show"
8
8
  - command: "az aks --help"
9
9
  - command: "kubectl version --client"
10
+
11
+ # Note: Tools in this toolset use transformers with llm_summarize
12
+ # to automatically summarize large JSON outputs from Azure CLI commands
13
+ # when a fast model is configured, focusing on key configuration and status information.
10
14
  tools:
11
15
  - name: "cloud_provider"
12
16
  description: "Fetches the cloud provider of the kubernetes cluster, determined by the providerID of the nodes"
@@ -18,16 +22,61 @@ toolsets:
18
22
  user_description: "get AKS cluster {{ CLUSTER_NAME }} under resource group {{ RESOURCE_GROUP_NAME }} in subscription {{ SUBSCRIPTION_ID }}"
19
23
  command: |
20
24
  az aks show --resource-group {{ RESOURCE_GROUP_NAME }} --name {{ CLUSTER_NAME }} --subscription {{ SUBSCRIPTION_ID }}
25
+ transformers:
26
+ - name: llm_summarize
27
+ config:
28
+ input_threshold: 1500
29
+ prompt: |
30
+ Summarize this AKS cluster configuration focusing on:
31
+ - Cluster status, health state, and version information
32
+ - Node pool configuration and scaling settings
33
+ - Network configuration (subnet, load balancer, network policy)
34
+ - Add-ons and features enabled (monitoring, auto-scaling, etc.)
35
+ - Security settings (RBAC, managed identity, private cluster)
36
+ - Any warnings or deprecated configurations
37
+ - When possible, highlight settings that might impact performance or security
38
+ - Be concise: aim for ≤ 50% of the original length; avoid repeating defaults/healthy/unchanged details
39
+ - Prefer aggregates and counts; list only outliers and actionable items
40
+ - Keep grep-friendly: include exact field names/values that matter
21
41
  - name: "aks_list_clusters_by_rg"
22
42
  description: "Lists all AKS clusters under a specific resource group. Only run this tool when you need to get all clusters in a resource group, rather than a specific one."
23
43
  user_description: "list AKS clusters in resource group {{ RESOURCE_GROUP_NAME }} under subscription {{ SUBSCRIPTION_ID }}"
24
44
  command: |
25
45
  az aks list --resource-group {{ RESOURCE_GROUP_NAME }} --subscription {{ SUBSCRIPTION_ID }}
46
+ transformers:
47
+ - name: llm_summarize
48
+ config:
49
+ input_threshold: 1000
50
+ prompt: |
51
+ Summarize this AKS clusters list focusing on:
52
+ - Cluster names, locations, and current status
53
+ - Kubernetes versions and any version skew issues
54
+ - Node pool counts and VM SKUs
55
+ - Key configuration differences between clusters
56
+ - Any clusters in error or unusual states
57
+ - When possible, group clusters by similar configurations
58
+ - Be concise and avoid expansion: target ≤ 50% of input size; prefer counts + outliers over full listings
59
+ - Include grep-ready keys/values; avoid repeating entire objects or unchanged defaults
26
60
  - name: "aks_list_node_pools"
27
61
  description: "Lists node pools in an AKS cluster"
28
62
  user_description: "list node pools for AKS cluster {{ CLUSTER_NAME }} under resource group {{ RESOURCE_GROUP_NAME }}"
29
63
  command: |
30
64
  az aks nodepool list --resource-group {{ RESOURCE_GROUP_NAME }} --cluster-name {{ CLUSTER_NAME }} --subscription {{ SUBSCRIPTION_ID }}
65
+ transformers:
66
+ - name: llm_summarize
67
+ config:
68
+ input_threshold: 1200
69
+ prompt: |
70
+ Summarize this AKS node pools list focusing on:
71
+ - Node pool names, VM sizes, and current node counts
72
+ - Scaling configuration (min/max nodes, auto-scaling enabled)
73
+ - Node pool status and provisioning state
74
+ - OS types, Kubernetes versions, and any upgrade patterns
75
+ - Taints, labels, and specialized configurations
76
+ - Any node pools in error states or with scaling issues
77
+ - When possible, identify resource allocation patterns
78
+ - Strive for ≤ 50% of the original size; keep results compact and grep-friendly (one line per aggregate)
79
+ - Prioritize aggregates and actionable outliers over comprehensive details
31
80
  - name: "aks_show_node_pool"
32
81
  description: "Shows details of a specific node pool in an AKS cluster"
33
82
  user_description: "get node pool {{ NODE_POOL_NAME }} in AKS cluster {{ CLUSTER_NAME }} under resource group {{ RESOURCE_GROUP_NAME }}"
@@ -84,3 +133,18 @@ toolsets:
84
133
  user_description: "list NSG rules for NSG {{ NSG_NAME }} in resource group {{ RESOURCE_GROUP_NAME }} under subscription {{ SUBSCRIPTION_ID }}"
85
134
  command: |
86
135
  az network nsg rule list --resource-group {{ RESOURCE_GROUP_NAME }} --nsg-name {{ NSG_NAME }} --subscription {{ SUBSCRIPTION_ID }} --include-default -o table
136
+ transformers:
137
+ - name: llm_summarize
138
+ config:
139
+ input_threshold: 1000
140
+ prompt: |
141
+ Summarize these NSG rules focusing on:
142
+ - Allow vs deny rules and their priority order
143
+ - Inbound vs outbound traffic rules
144
+ - Port ranges and protocols affected
145
+ - Source and destination configurations
146
+ - Any overly permissive or potentially insecure rules
147
+ - Default rules vs custom rules
148
+ - When possible, highlight rules that might impact AKS connectivity
149
+ - Be concise: aim for ≤ 50% of the original text; prioritize aggregates and actionable outliers
150
+ - Include grep-ready keys/values; avoid repeating entire rules or unchanged defaults
@@ -1,23 +1,25 @@
1
- import requests # type: ignore
1
+ import gzip
2
+ import io
2
3
  import logging
3
- from typing import Any, Dict, Tuple, List
4
+ import os
5
+ from collections import Counter
6
+ from datetime import datetime, timedelta, timezone
7
+ from typing import Any, Dict, List, Tuple
8
+
9
+ import requests # type: ignore
10
+ from pydantic import BaseModel, PrivateAttr
11
+ from requests.auth import HTTPDigestAuth # type: ignore
12
+
4
13
  from holmes.core.tools import (
5
14
  CallablePrerequisite,
15
+ StructuredToolResult,
16
+ StructuredToolResultStatus,
6
17
  Tool,
18
+ ToolInvokeContext,
7
19
  ToolParameter,
8
20
  Toolset,
9
21
  ToolsetTag,
10
22
  )
11
-
12
- from pydantic import BaseModel, PrivateAttr
13
- from holmes.core.tools import StructuredToolResult, ToolResultStatus
14
- from requests.auth import HTTPDigestAuth # type: ignore
15
- import gzip
16
- import io
17
- from datetime import datetime, timedelta, timezone
18
- import os
19
- from collections import Counter
20
-
21
23
  from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
22
24
 
23
25
 
@@ -41,7 +43,6 @@ class MongoDBAtlasToolset(Toolset):
41
43
  def __init__(self):
42
44
  super().__init__(
43
45
  prerequisites=[CallablePrerequisite(callable=self.prerequisites_callable)],
44
- experimental=True,
45
46
  tools=[
46
47
  ReturnProjectAlerts(toolset=self),
47
48
  ReturnProjectProcesses(toolset=self),
@@ -66,8 +67,8 @@ class MongoDBAtlasToolset(Toolset):
66
67
  {"Accept": "application/vnd.atlas.2025-03-12+json"}
67
68
  )
68
69
  self._session.auth = HTTPDigestAuth(
69
- self.config.get("public_key"),
70
- self.config.get("private_key"),
70
+ self.config.get("public_key"), # type: ignore
71
+ self.config.get("private_key"), # type: ignore
71
72
  )
72
73
  return True, ""
73
74
  except Exception:
@@ -90,15 +91,15 @@ class MongoDBAtlasBaseTool(Tool):
90
91
  if response.ok:
91
92
  res = response.json()
92
93
  return StructuredToolResult(
93
- status=ToolResultStatus.SUCCESS
94
+ status=StructuredToolResultStatus.SUCCESS
94
95
  if res.get(field, [])
95
- else ToolResultStatus.NO_DATA,
96
+ else StructuredToolResultStatus.NO_DATA,
96
97
  data=res,
97
98
  params=params,
98
99
  )
99
100
  else:
100
101
  return StructuredToolResult(
101
- status=ToolResultStatus.ERROR,
102
+ status=StructuredToolResultStatus.ERROR,
102
103
  error=f"Failed {self.name}.\n{response.text}",
103
104
  return_code=response.status_code,
104
105
  params=params,
@@ -118,9 +119,7 @@ class ReturnProjectAlerts(MongoDBAtlasBaseTool):
118
119
  project_id = self.toolset.config.get("project_id", "")
119
120
  return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Project Alerts ({project_id})"
120
121
 
121
- def _invoke(
122
- self, params: dict, user_approved: bool = False
123
- ) -> StructuredToolResult:
122
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
124
123
  try:
125
124
  url = "https://cloud.mongodb.com/api/atlas/v2/groups/{project_id}/alerts".format(
126
125
  project_id=self.toolset.config.get("project_id")
@@ -130,7 +129,7 @@ class ReturnProjectAlerts(MongoDBAtlasBaseTool):
130
129
  except Exception as e:
131
130
  logging.exception(self.get_parameterized_one_liner(params))
132
131
  return StructuredToolResult(
133
- status=ToolResultStatus.ERROR,
132
+ status=StructuredToolResultStatus.ERROR,
134
133
  data=f"Exception {self.name}: {str(e)}",
135
134
  params=params,
136
135
  )
@@ -145,9 +144,7 @@ class ReturnProjectProcesses(MongoDBAtlasBaseTool):
145
144
  project_id = self.toolset.config.get("project_id", "")
146
145
  return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Project Processes ({project_id})"
147
146
 
148
- def _invoke(
149
- self, params: dict, user_approved: bool = False
150
- ) -> StructuredToolResult:
147
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
151
148
  try:
152
149
  url = "https://cloud.mongodb.com/api/atlas/v2/groups/{project_id}/processes".format(
153
150
  project_id=self.toolset.config.get("project_id")
@@ -157,7 +154,7 @@ class ReturnProjectProcesses(MongoDBAtlasBaseTool):
157
154
  except Exception as e:
158
155
  logging.exception(self.get_parameterized_one_liner(params))
159
156
  return StructuredToolResult(
160
- status=ToolResultStatus.ERROR,
157
+ status=StructuredToolResultStatus.ERROR,
161
158
  error=f"Exception {self.name}: {str(e)}",
162
159
  params=params,
163
160
  )
@@ -180,9 +177,7 @@ class ReturnProjectSlowQueries(MongoDBAtlasBaseTool):
180
177
  process_id = params.get("process_id", "")
181
178
  return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Slow Queries ({process_id})"
182
179
 
183
- def _invoke(
184
- self, params: dict, user_approved: bool = False
185
- ) -> StructuredToolResult:
180
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
186
181
  try:
187
182
  url = self.url.format(
188
183
  project_id=self.toolset.config.get("project_id"),
@@ -193,7 +188,7 @@ class ReturnProjectSlowQueries(MongoDBAtlasBaseTool):
193
188
  except Exception as e:
194
189
  logging.exception(self.get_parameterized_one_liner(params))
195
190
  return StructuredToolResult(
196
- status=ToolResultStatus.ERROR,
191
+ status=StructuredToolResultStatus.ERROR,
197
192
  error=f"Exception {self.name}: {str(e)}",
198
193
  params=params,
199
194
  )
@@ -209,9 +204,7 @@ class ReturnEventsFromProject(MongoDBAtlasBaseTool):
209
204
  project_id = self.toolset.config.get("project_id", "")
210
205
  return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Project Events ({project_id})"
211
206
 
212
- def _invoke(
213
- self, params: dict, user_approved: bool = False
214
- ) -> StructuredToolResult:
207
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
215
208
  params.update({"itemsPerPage": 500})
216
209
  try:
217
210
  now_utc = datetime.now(timezone.utc)
@@ -230,14 +223,14 @@ class ReturnEventsFromProject(MongoDBAtlasBaseTool):
230
223
  )
231
224
  data = f"last 4 hours eventTypeName and # of occurrences list: {events_counter} \n to get more information about a given eventTypeName call atlas_return_events_type_from_project"
232
225
  status = (
233
- ToolResultStatus.SUCCESS
226
+ StructuredToolResultStatus.SUCCESS
234
227
  if events_counter
235
- else ToolResultStatus.NO_DATA
228
+ else StructuredToolResultStatus.NO_DATA
236
229
  )
237
230
  return StructuredToolResult(status=status, data=data, params=params)
238
231
  else:
239
232
  return StructuredToolResult(
240
- status=ToolResultStatus.ERROR,
233
+ status=StructuredToolResultStatus.ERROR,
241
234
  error=f"Failed {self.name}. \n{response.text}",
242
235
  return_code=response.status_code,
243
236
  params=params,
@@ -245,7 +238,7 @@ class ReturnEventsFromProject(MongoDBAtlasBaseTool):
245
238
  except Exception as e:
246
239
  logging.exception(self.get_parameterized_one_liner(params))
247
240
  return StructuredToolResult(
248
- status=ToolResultStatus.ERROR,
241
+ status=StructuredToolResultStatus.ERROR,
249
242
  error=f"Exception {self.name}: {str(e)}",
250
243
  params=params,
251
244
  )
@@ -268,9 +261,7 @@ class ReturnLogsForProcessInProject(MongoDBAtlasBaseTool):
268
261
  hostname = params.get("hostName", "")
269
262
  return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Host Logs ({hostname})"
270
263
 
271
- def _invoke(
272
- self, params: dict, user_approved: bool = False
273
- ) -> StructuredToolResult:
264
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
274
265
  one_hour_ago = datetime.now(timezone.utc) - timedelta(hours=1)
275
266
  try:
276
267
  url = self.url.format(
@@ -287,11 +278,13 @@ class ReturnLogsForProcessInProject(MongoDBAtlasBaseTool):
287
278
  with gzip.GzipFile(fileobj=io.BytesIO(response.content)) as gz:
288
279
  text_data = gz.read().decode("utf-8")
289
280
  return StructuredToolResult(
290
- status=ToolResultStatus.SUCCESS, data=text_data, params=params
281
+ status=StructuredToolResultStatus.SUCCESS,
282
+ data=text_data,
283
+ params=params,
291
284
  )
292
285
  else:
293
286
  return StructuredToolResult(
294
- status=ToolResultStatus.ERROR,
287
+ status=StructuredToolResultStatus.ERROR,
295
288
  error=f"Failed {self.name}. \n{response.text}",
296
289
  return_code=response.status_code,
297
290
  params=params,
@@ -299,7 +292,7 @@ class ReturnLogsForProcessInProject(MongoDBAtlasBaseTool):
299
292
  except Exception as e:
300
293
  logging.exception(self.get_parameterized_one_liner(params))
301
294
  return StructuredToolResult(
302
- status=ToolResultStatus.ERROR,
295
+ status=StructuredToolResultStatus.ERROR,
303
296
  error=f"Exception {self.name}: {str(e)}",
304
297
  params=params,
305
298
  )
@@ -322,9 +315,7 @@ class ReturnEventTypeFromProject(MongoDBAtlasBaseTool):
322
315
  event_type = params.get("eventType", "")
323
316
  return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Event Details ({event_type})"
324
317
 
325
- def _invoke(
326
- self, params: dict, user_approved: bool = False
327
- ) -> StructuredToolResult:
318
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
328
319
  try:
329
320
  url = self.url.format(projectId=self.toolset.config.get("project_id"))
330
321
 
@@ -340,7 +331,7 @@ class ReturnEventTypeFromProject(MongoDBAtlasBaseTool):
340
331
  except Exception as e:
341
332
  logging.exception(self.get_parameterized_one_liner(params))
342
333
  return StructuredToolResult(
343
- status=ToolResultStatus.ERROR,
334
+ status=StructuredToolResultStatus.ERROR,
344
335
  error=f"Exception {self.name}: {str(e)}",
345
336
  params=params,
346
337
  )
@@ -1,6 +1,7 @@
1
- from typing import Dict, List, Any
2
1
  import logging
3
- from datetime import datetime, timezone, timedelta
2
+ from datetime import datetime, timedelta, timezone
3
+ from typing import Any, Dict, List
4
+
4
5
  from azure.core.credentials import TokenCredential
5
6
  from azure.mgmt.monitor import MonitorManagementClient
6
7
  from azure.mgmt.resource import ResourceManagementClient
@@ -1,6 +1,7 @@
1
- from typing import Dict, List
2
1
  import logging
3
2
  import struct
3
+ from typing import Dict, List
4
+
4
5
  from azure.core.credentials import TokenCredential
5
6
  from azure.mgmt.sql import SqlManagementClient
6
7
 
@@ -1,6 +1,7 @@
1
- from typing import Dict, List, Any
2
1
  import logging
3
- from datetime import datetime, timezone, timedelta
2
+ from datetime import datetime, timedelta, timezone
3
+ from typing import Any, Dict, List
4
+
4
5
  from azure.core.credentials import TokenCredential
5
6
  from azure.mgmt.monitor import MonitorManagementClient
6
7
 
@@ -1,8 +1,10 @@
1
- from typing import Dict, List
2
1
  import logging
3
2
  from datetime import datetime, timedelta
3
+ from typing import Dict, List
4
+
4
5
  from azure.core.credentials import TokenCredential
5
6
  from azure.monitor.query import MetricsQueryClient
7
+
6
8
  from .azure_sql_api import AzureSQLAPIClient
7
9
 
8
10
 
@@ -1,8 +1,10 @@
1
- from typing import Dict, List
2
1
  import logging
3
2
  from datetime import datetime, timedelta
3
+ from typing import Dict, List
4
+
4
5
  from azure.core.credentials import TokenCredential
5
6
  from azure.monitor.query import MetricsQueryClient
7
+
6
8
  from .azure_sql_api import AzureSQLAPIClient
7
9
 
8
10
 
@@ -1,19 +1,24 @@
1
- import os
2
1
  import logging
2
+ import os
3
3
  from typing import Any, Dict, Tuple, Union
4
4
 
5
- from azure.identity import DefaultAzureCredential, ClientSecretCredential
5
+ from azure.identity import ClientSecretCredential, DefaultAzureCredential
6
6
 
7
7
  from holmes.core.tools import (
8
8
  CallablePrerequisite,
9
9
  ToolsetTag,
10
10
  )
11
11
  from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
12
- from holmes.plugins.toolsets.consts import TOOLSET_CONFIG_MISSING_ERROR
13
12
  from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
14
- BaseAzureSQLToolset,
15
13
  AzureSQLConfig,
16
14
  AzureSQLDatabaseConfig,
15
+ BaseAzureSQLToolset,
16
+ )
17
+ from holmes.plugins.toolsets.azure_sql.tools.analyze_connection_failures import (
18
+ AnalyzeConnectionFailures,
19
+ )
20
+ from holmes.plugins.toolsets.azure_sql.tools.analyze_database_connections import (
21
+ AnalyzeDatabaseConnections,
17
22
  )
18
23
 
19
24
  # Import all tool classes
@@ -23,24 +28,19 @@ from holmes.plugins.toolsets.azure_sql.tools.analyze_database_health_status impo
23
28
  from holmes.plugins.toolsets.azure_sql.tools.analyze_database_performance import (
24
29
  AnalyzeDatabasePerformance,
25
30
  )
26
- from holmes.plugins.toolsets.azure_sql.tools.analyze_database_connections import (
27
- AnalyzeDatabaseConnections,
28
- )
29
31
  from holmes.plugins.toolsets.azure_sql.tools.analyze_database_storage import (
30
32
  AnalyzeDatabaseStorage,
31
33
  )
32
- from holmes.plugins.toolsets.azure_sql.tools.get_top_cpu_queries import GetTopCPUQueries
34
+ from holmes.plugins.toolsets.azure_sql.tools.get_active_alerts import GetActiveAlerts
33
35
  from holmes.plugins.toolsets.azure_sql.tools.get_slow_queries import GetSlowQueries
36
+ from holmes.plugins.toolsets.azure_sql.tools.get_top_cpu_queries import GetTopCPUQueries
34
37
  from holmes.plugins.toolsets.azure_sql.tools.get_top_data_io_queries import (
35
38
  GetTopDataIOQueries,
36
39
  )
37
40
  from holmes.plugins.toolsets.azure_sql.tools.get_top_log_io_queries import (
38
41
  GetTopLogIOQueries,
39
42
  )
40
- from holmes.plugins.toolsets.azure_sql.tools.get_active_alerts import GetActiveAlerts
41
- from holmes.plugins.toolsets.azure_sql.tools.analyze_connection_failures import (
42
- AnalyzeConnectionFailures,
43
- )
43
+ from holmes.plugins.toolsets.consts import TOOLSET_CONFIG_MISSING_ERROR
44
44
 
45
45
 
46
46
  class AzureSQLToolset(BaseAzureSQLToolset):
@@ -60,7 +60,6 @@ class AzureSQLToolset(BaseAzureSQLToolset):
60
60
  docs_url="https://kagi.com/proxy/png-clipart-microsoft-sql-server-microsoft-azure-sql-database-microsoft-text-logo-thumbnail.png?c=4Sg1bvcUGOrhnDzXgoBBa0G0j27ykgskX4a8cLrZp_quzqlpVGVG02OqQtezTxy7lB6ydmTKgbVAn_F7BxofxK6LKKUZSpjJ1huIAsXPVaXyakO4sWXFiX0Wz_8WjkA0AIlO_oFfW31AKaj5RcvGcr3siy0n5kW-GcqdpeBWsmm_huxUT6RycULFCDFBwuUzHvVl5TW3cYqlMxT8ecPZfg%3D%3D",
61
61
  icon_url="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Azure_SQL_Database_logo.svg/1200px-Azure_SQL_Database_logo.svg.png",
62
62
  tags=[ToolsetTag.CORE],
63
- experimental=True,
64
63
  tools=[
65
64
  AnalyzeDatabaseHealthStatus(self),
66
65
  AnalyzeDatabasePerformance(self),
@@ -1,17 +1,22 @@
1
1
  import logging
2
- from typing import Dict, Tuple
3
2
  from datetime import datetime, timezone
3
+ from typing import Dict, Tuple
4
4
 
5
- from holmes.core.tools import StructuredToolResult, ToolParameter, ToolResultStatus
6
- from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
7
- BaseAzureSQLTool,
8
- BaseAzureSQLToolset,
9
- AzureSQLDatabaseConfig,
5
+ from holmes.core.tools import (
6
+ StructuredToolResult,
7
+ StructuredToolResultStatus,
8
+ ToolInvokeContext,
9
+ ToolParameter,
10
10
  )
11
11
  from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
12
12
  from holmes.plugins.toolsets.azure_sql.apis.connection_failure_api import (
13
13
  ConnectionFailureAPI,
14
14
  )
15
+ from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
16
+ AzureSQLDatabaseConfig,
17
+ BaseAzureSQLTool,
18
+ BaseAzureSQLToolset,
19
+ )
15
20
  from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
16
21
 
17
22
 
@@ -213,9 +218,7 @@ class AnalyzeConnectionFailures(BaseAzureSQLTool):
213
218
 
214
219
  return "\n".join(report_sections)
215
220
 
216
- def _invoke(
217
- self, params: dict, user_approved: bool = False
218
- ) -> StructuredToolResult:
221
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
219
222
  try:
220
223
  # Get configuration
221
224
  db_config = self.toolset.database_config()
@@ -242,7 +245,7 @@ class AnalyzeConnectionFailures(BaseAzureSQLTool):
242
245
  # Check for errors
243
246
  if "error" in analysis_data:
244
247
  return StructuredToolResult(
245
- status=ToolResultStatus.ERROR,
248
+ status=StructuredToolResultStatus.ERROR,
246
249
  error=analysis_data["error"],
247
250
  params=params,
248
251
  )
@@ -253,7 +256,7 @@ class AnalyzeConnectionFailures(BaseAzureSQLTool):
253
256
  )
254
257
 
255
258
  return StructuredToolResult(
256
- status=ToolResultStatus.SUCCESS,
259
+ status=StructuredToolResultStatus.SUCCESS,
257
260
  data=report_text,
258
261
  params=params,
259
262
  )
@@ -263,7 +266,7 @@ class AnalyzeConnectionFailures(BaseAzureSQLTool):
263
266
  f"Error in analyze_connection_failures: {str(e)}", exc_info=True
264
267
  )
265
268
  return StructuredToolResult(
266
- status=ToolResultStatus.ERROR,
269
+ status=StructuredToolResultStatus.ERROR,
267
270
  error=f"Failed to analyze connection failures: {str(e)}",
268
271
  params=params,
269
272
  )
@@ -1,17 +1,22 @@
1
1
  import logging
2
- from typing import Any, Dict, Tuple
3
2
  from datetime import datetime, timezone
3
+ from typing import Any, Dict, Tuple
4
4
 
5
- from holmes.core.tools import StructuredToolResult, ToolParameter, ToolResultStatus
6
- from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
7
- BaseAzureSQLTool,
8
- BaseAzureSQLToolset,
9
- AzureSQLDatabaseConfig,
5
+ from holmes.core.tools import (
6
+ StructuredToolResult,
7
+ StructuredToolResultStatus,
8
+ ToolInvokeContext,
9
+ ToolParameter,
10
10
  )
11
+ from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
11
12
  from holmes.plugins.toolsets.azure_sql.apis.connection_monitoring_api import (
12
13
  ConnectionMonitoringAPI,
13
14
  )
14
- from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
15
+ from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
16
+ AzureSQLDatabaseConfig,
17
+ BaseAzureSQLTool,
18
+ BaseAzureSQLToolset,
19
+ )
15
20
  from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
16
21
 
17
22
 
@@ -151,9 +156,7 @@ class AnalyzeDatabaseConnections(BaseAzureSQLTool):
151
156
 
152
157
  return "\n".join(report_sections)
153
158
 
154
- def _invoke(
155
- self, params: dict, user_approved: bool = False
156
- ) -> StructuredToolResult:
159
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
157
160
  try:
158
161
  hours_back = params.get("hours_back", 2)
159
162
 
@@ -200,7 +203,7 @@ class AnalyzeDatabaseConnections(BaseAzureSQLTool):
200
203
  )
201
204
 
202
205
  return StructuredToolResult(
203
- status=ToolResultStatus.SUCCESS,
206
+ status=StructuredToolResultStatus.SUCCESS,
204
207
  data=report_text,
205
208
  params=params,
206
209
  )
@@ -208,7 +211,7 @@ class AnalyzeDatabaseConnections(BaseAzureSQLTool):
208
211
  error_msg = f"Failed to generate connection report: {str(e)}"
209
212
  logging.error(error_msg)
210
213
  return StructuredToolResult(
211
- status=ToolResultStatus.ERROR,
214
+ status=StructuredToolResultStatus.ERROR,
212
215
  error=error_msg,
213
216
  params=params,
214
217
  )
@@ -1,16 +1,18 @@
1
1
  import logging
2
- from typing import Dict
3
2
  from datetime import datetime, timezone
3
+ from typing import Dict, Tuple
4
4
 
5
- from holmes.core.tools import StructuredToolResult, ToolResultStatus
5
+ from holmes.core.tools import (
6
+ StructuredToolResult,
7
+ StructuredToolResultStatus,
8
+ ToolInvokeContext,
9
+ )
10
+ from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
6
11
  from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
12
+ AzureSQLDatabaseConfig,
7
13
  BaseAzureSQLTool,
8
14
  BaseAzureSQLToolset,
9
- AzureSQLDatabaseConfig,
10
15
  )
11
- from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
12
- from typing import Tuple
13
-
14
16
  from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
15
17
 
16
18
 
@@ -131,9 +133,7 @@ class AnalyzeDatabaseHealthStatus(BaseAzureSQLTool):
131
133
 
132
134
  return "\n".join(report_sections)
133
135
 
134
- def _invoke(
135
- self, params: dict, user_approved: bool = False
136
- ) -> StructuredToolResult:
136
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
137
137
  try:
138
138
  db_config = self.toolset.database_config()
139
139
  client = self.toolset.api_client()
@@ -145,7 +145,7 @@ class AnalyzeDatabaseHealthStatus(BaseAzureSQLTool):
145
145
  report_text = self._build_health_report(health_data, db_config)
146
146
 
147
147
  return StructuredToolResult(
148
- status=ToolResultStatus.SUCCESS,
148
+ status=StructuredToolResultStatus.SUCCESS,
149
149
  data=report_text,
150
150
  params=params,
151
151
  )
@@ -153,7 +153,7 @@ class AnalyzeDatabaseHealthStatus(BaseAzureSQLTool):
153
153
  error_msg = f"Failed to generate health report: {str(e)}"
154
154
  logging.error(error_msg)
155
155
  return StructuredToolResult(
156
- status=ToolResultStatus.ERROR,
156
+ status=StructuredToolResultStatus.ERROR,
157
157
  error=error_msg,
158
158
  params=params,
159
159
  )
@@ -1,14 +1,18 @@
1
1
  import logging
2
- from typing import Any, Dict, List, Tuple, cast
3
2
  from datetime import datetime, timezone
3
+ from typing import Any, Dict, List, Tuple, cast
4
4
 
5
- from holmes.core.tools import StructuredToolResult, ToolResultStatus
5
+ from holmes.core.tools import (
6
+ StructuredToolResult,
7
+ StructuredToolResultStatus,
8
+ ToolInvokeContext,
9
+ )
10
+ from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
6
11
  from holmes.plugins.toolsets.azure_sql.azure_base_toolset import (
12
+ AzureSQLDatabaseConfig,
7
13
  BaseAzureSQLTool,
8
14
  BaseAzureSQLToolset,
9
- AzureSQLDatabaseConfig,
10
15
  )
11
- from holmes.plugins.toolsets.azure_sql.apis.azure_sql_api import AzureSQLAPIClient
12
16
  from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
13
17
 
14
18
 
@@ -192,9 +196,7 @@ class AnalyzeDatabasePerformance(BaseAzureSQLTool):
192
196
 
193
197
  return "\n".join(report_sections)
194
198
 
195
- def _invoke(
196
- self, params: dict, user_approved: bool = False
197
- ) -> StructuredToolResult:
199
+ def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
198
200
  try:
199
201
  db_config = self.toolset.database_config()
200
202
  client = self.toolset.api_client()
@@ -206,7 +208,7 @@ class AnalyzeDatabasePerformance(BaseAzureSQLTool):
206
208
  report_text = self._build_performance_report(performance_data, db_config)
207
209
 
208
210
  return StructuredToolResult(
209
- status=ToolResultStatus.SUCCESS,
211
+ status=StructuredToolResultStatus.SUCCESS,
210
212
  data=report_text,
211
213
  params=params,
212
214
  )
@@ -214,7 +216,7 @@ class AnalyzeDatabasePerformance(BaseAzureSQLTool):
214
216
  error_msg = f"Failed to generate performance report: {str(e)}"
215
217
  logging.error(error_msg)
216
218
  return StructuredToolResult(
217
- status=ToolResultStatus.ERROR,
219
+ status=StructuredToolResultStatus.ERROR,
218
220
  error=error_msg,
219
221
  params=params,
220
222
  )