Conversation
…pth filtering Extends JsonFilterMixin (jq + max_depth parameters) to Python toolsets that return JSON responses but previously had no client-side filtering support. This helps the LLM constrain large API responses and extract specific fields. Toolsets updated: - Elasticsearch: IndexStats, NodesStats - ServiceNow: GetRecords, GetRecord (via base class) - Datadog General: DatadogAPIGet, DatadogAPIPostSearch - NewRelic: ExecuteNRQLQuery - Coralogix: ExecuteDataPrimeQuery - MongoDB Atlas: base class + SlowQueries, EventType tools - RabbitMQ: GetRabbitMQClusterStatus https://claude.ai/code/session_01K4kVdXWMnMv5ZQMntw9shn Signed-off-by: Claude <noreply@anthropic.com>
📂 Previous Runs📜 Run @ a94c2de (#22807630268)✅ Results of HolmesGPT evalsAutomatically triggered by commit a94c2de on branch Results of HolmesGPT evals
Benchmark Comparison DetailsBaseline: latest ci-benchmark experiment on master Status: Success - 61 test/model combinations loaded Benchmark experiment:
Time comparison (seconds):
Benchmark has no cost, total tokens, cached tokens data. Will appear after the next weekly benchmark run. Comparison indicators:
📜 Run @ a323f89 (#22807289617)✅ Results of HolmesGPT evalsAutomatically triggered by commit a323f89 on branch Results of HolmesGPT evals
Benchmark Comparison DetailsBaseline: latest ci-benchmark experiment on master Status: Success - 61 test/model combinations loaded Benchmark experiment:
Time comparison (seconds):
Benchmark has no cost, total tokens, cached tokens data. Will appear after the next weekly benchmark run. Comparison indicators:
✅ Results of HolmesGPT evalsAutomatically triggered by commit 2a6b3bb on branch Results of HolmesGPT evals
Benchmark comparison unavailable: No ci-benchmark experiments found Benchmark Comparison DetailsBaseline: latest ci-benchmark experiment on master Status: No ci-benchmark experiments found Comparison indicators:
📖 Legend
🔄 Re-run evals manually
Option 1: Comment on this PR with Or with more options (one per line): Run evals on a different branch (e.g., master) for comparison:
Quick re-run: Use Option 2: Trigger via GitHub Actions UI → "Run workflow" Option 3: Add PR labels to include extra evals in automatic regression runs:
Examples: 🏷️ Valid tags
Commands: CLI: |
|
✅ Docker images ready for
Use these tags to pull the images for testing. 📋 Copy commandsgcloud auth configure-docker us-central1-docker.pkg.dev
docker pull us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes:472b780f
docker tag us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes:472b780f me-west1-docker.pkg.dev/robusta-development/development/holmes-dev:472b780f
docker push me-west1-docker.pkg.dev/robusta-development/development/holmes-dev:472b780f
docker pull us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes-operator:472b780f
docker tag us-central1-docker.pkg.dev/robusta-development/temporary-builds/holmes-operator:472b780f me-west1-docker.pkg.dev/robusta-development/development/holmes-operator-dev:472b780f
docker push me-west1-docker.pkg.dev/robusta-development/development/holmes-operator-dev:472b780fPatch Helm values in one line (choose the chart you use): HolmesGPT chart: helm upgrade --install holmesgpt ./helm/holmes \
--set registry=me-west1-docker.pkg.dev/robusta-development/development \
--set image=holmes-dev:472b780f \
--set operator.registry=me-west1-docker.pkg.dev/robusta-development/development \
--set operator.image=holmes-operator-dev:472b780fRobusta wrapper chart: helm upgrade --install robusta robusta/robusta \
--reuse-values \
--set holmes.registry=me-west1-docker.pkg.dev/robusta-development/development \
--set holmes.image=holmes-dev:472b780f \
--set holmes.operator.registry=me-west1-docker.pkg.dev/robusta-development/development \
--set holmes.operator.image=holmes-operator-dev:472b780f |
WalkthroughApplies JsonFilterMixin across multiple toolsets: adds the mixin to tool class inheritance, wraps tool parameter declarations with JsonFilterMixin.extend_parameters(...), and routes returned results through self.filter_result(...) before returning. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for holmes-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
🔬 CLI Performance Benchmark🟡 Startup Time (no LLM)Measures
🟡 Full CLI with LLMMeasures
PR: |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py (1)
338-342:⚠️ Potential issue | 🟠 MajorFiltering parameters will leak to MongoDB Atlas API.
The
paramsdict is passed directly tosession.get()as query parameters. WithJsonFilterMixin.extend_parameters()addingjqandmax_depthto the parameters, these will be sent to the MongoDB Atlas API, potentially causing request failures if the API rejects unknown parameters.Compare with
ReturnProjectSlowQueries(line 199) which doesn't pass params to the API request.🐛 Proposed fix: Extract filtering params before API call
def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult: try: url = self.url.format(projectId=self.toolset.config.get("project_id")) now_utc = datetime.now(timezone.utc) four_hours_ago = now_utc - timedelta(hours=4) iso_timestamp = four_hours_ago.isoformat() - params.update({"itemsPerPage": 500, "minDate": iso_timestamp}) + api_params = { + "eventType": params.get("eventType"), + "itemsPerPage": 500, + "minDate": iso_timestamp, + } response = self.toolset._session.get( url=url, - params=params, + params=api_params, ) return self.return_result(response, params)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py` around lines 338 - 342, The params dict created in mongodb_atlas.py is being sent directly to self.toolset._session.get, which leaks JsonFilterMixin.extend_parameters() keys like jq and max_depth to the MongoDB Atlas API; update the code to separate filtering args from API query params by calling JsonFilterMixin.extend_parameters (or reusing the existing params) to collect filter keys, then build a new api_params (e.g., copy of params) and remove/filter out jq, max_depth (and any other filter-only keys) before calling self.toolset._session.get; follow the pattern used in ReturnProjectSlowQueries to ensure only Atlas-accepted parameters are sent.
🧹 Nitpick comments (2)
holmes/plugins/toolsets/coralogix/toolset_coralogix.py (1)
180-186: Filtering correctly applied to the result.The
filter_result()call properly wraps theStructuredToolResultbefore returning.Minor note: The variable
resultshadows the earlierresultfrom line 142 (the API response tuple). While not a bug since the original is no longer needed after line 179, using a distinct name likestructured_resultcould improve readability.,
♻️ Optional: Avoid variable shadowing for clarity
- result = StructuredToolResult( + structured_result = StructuredToolResult( status=status, data=final_result, params=params, url=explore_url, ) - return self.filter_result(result, params) + return self.filter_result(structured_result, params)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@holmes/plugins/toolsets/coralogix/toolset_coralogix.py` around lines 180 - 186, The local variable named result that holds the StructuredToolResult shadows an earlier variable named result (the API response tuple); rename the StructuredToolResult variable to a distinct name such as structured_result and update its creation and the subsequent return call (StructuredToolResult(...) assigned to structured_result and return self.filter_result(structured_result, params)) so the earlier API response variable and the new structured result are not confused when reading functions like StructuredToolResult and filter_result.holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py (1)
64-88: Consider addingJsonFilterMixintoListConfiguredClustersfor consistency.While
ListConfiguredClustersreturns bounded configuration data (only user-configured clusters), addingJsonFilterMixinwould provide consistency across the toolset and allow users to filter the response if needed. This is optional since the data is inherently bounded by configuration.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py` around lines 64 - 88, Add JsonFilterMixin to the ListConfiguredClusters class definition (e.g., class ListConfiguredClusters(JsonFilterMixin, BaseRabbitMQTool):) so the tool supports JSON filtering like other tools; after computing available_clusters, pass that list through the mixin's JSON filter helper (use the actual mixin method name found in JsonFilterMixin, e.g., self.filter_json(...) or apply_json_filter(...)) before constructing and returning the StructuredToolResult, and ensure the MRO places JsonFilterMixin before BaseRabbitMQTool.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py`:
- Around line 338-342: The params dict created in mongodb_atlas.py is being sent
directly to self.toolset._session.get, which leaks
JsonFilterMixin.extend_parameters() keys like jq and max_depth to the MongoDB
Atlas API; update the code to separate filtering args from API query params by
calling JsonFilterMixin.extend_parameters (or reusing the existing params) to
collect filter keys, then build a new api_params (e.g., copy of params) and
remove/filter out jq, max_depth (and any other filter-only keys) before calling
self.toolset._session.get; follow the pattern used in ReturnProjectSlowQueries
to ensure only Atlas-accepted parameters are sent.
---
Nitpick comments:
In `@holmes/plugins/toolsets/coralogix/toolset_coralogix.py`:
- Around line 180-186: The local variable named result that holds the
StructuredToolResult shadows an earlier variable named result (the API response
tuple); rename the StructuredToolResult variable to a distinct name such as
structured_result and update its creation and the subsequent return call
(StructuredToolResult(...) assigned to structured_result and return
self.filter_result(structured_result, params)) so the earlier API response
variable and the new structured result are not confused when reading functions
like StructuredToolResult and filter_result.
In `@holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py`:
- Around line 64-88: Add JsonFilterMixin to the ListConfiguredClusters class
definition (e.g., class ListConfiguredClusters(JsonFilterMixin,
BaseRabbitMQTool):) so the tool supports JSON filtering like other tools; after
computing available_clusters, pass that list through the mixin's JSON filter
helper (use the actual mixin method name found in JsonFilterMixin, e.g.,
self.filter_json(...) or apply_json_filter(...)) before constructing and
returning the StructuredToolResult, and ensure the MRO places JsonFilterMixin
before BaseRabbitMQTool.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 049cd631-905a-40be-935f-51f4e4922809
📒 Files selected for processing (8)
holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.pyholmes/plugins/toolsets/coralogix/toolset_coralogix.pyholmes/plugins/toolsets/datadog/toolset_datadog_general.pyholmes/plugins/toolsets/elasticsearch/elasticsearch.pyholmes/plugins/toolsets/newrelic/newrelic.pyholmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.pyholmes/plugins/toolsets/servicenow_tables/servicenow_tables.pytests/plugins/toolsets/datadog/test_toolset_datadog_general.py
… before JsonFilterMixin filtering ClusterStatus is a Pydantic BaseModel, which jq cannot process directly. Call model_dump() to convert to a plain dict before passing to filter_result(). https://claude.ai/code/session_01K4kVdXWMnMv5ZQMntw9shn Signed-off-by: Claude <noreply@anthropic.com>
…API specs Add three new cloud-only eval tests for the datadog/general toolset which previously had zero eval coverage: - 227: Monitor + dashboard correlation (multi-hop API navigation) - 228: Root cause analysis across multiple monitors (causal reasoning) - 229: Cross-resource audit with monitors, dashboards, and downtimes (hidden verification code in note widget) All three tests create/cleanup resources via Datadog API (no K8s needed). Tested with both Sonnet 4.5 and Opus 4.6 via OpenRouter - both pass 100%. Also add raw.githubusercontent.com to HTTP passthrough in conftest.py, needed for the datadog/general toolset to fetch Datadog OpenAPI specs during tests. https://claude.ai/code/session_01K4kVdXWMnMv5ZQMntw9shn Signed-off-by: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/llm/fixtures/test_ask_holmes/227_datadog_general_monitor_dashboard/test_case.yaml (1)
18-22: Consider addinginclude_tool_calls: truefor this multi-hop test.This test requires Holmes to perform 5 distinct API calls (list monitors, get monitor details, list dashboards, get dashboard details, correlate). Adding
include_tool_calls: truewould verify that Holmes actually invoked the tools rather than potentially hallucinating responses. The other two Datadog tests (228, 229) include this flag.Suggested addition
tags: - datadog - hard +include_tool_calls: true + setup_timeout: 120🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/llm/fixtures/test_ask_holmes/227_datadog_general_monitor_dashboard/test_case.yaml` around lines 18 - 22, This multi-hop Datadog test is missing the include_tool_calls flag, so update the test YAML to add include_tool_calls: true at the top-level of the test definition to ensure Holmes' tool invocations (list monitors, get monitor details, list dashboards, get dashboard details, correlate) are validated; locate the file test_ask_holmes/227_datadog_general_monitor_dashboard/test_case.yaml and add the include_tool_calls: true key alongside existing keys like tags and setup_timeout.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@tests/llm/fixtures/test_ask_holmes/229_datadog_general_cross_resource/test_case.yaml`:
- Around line 216-224: The resource validation currently checks M1_ID, M2_ID,
M3_ID, and DASH_ID but omits DT_ID; update the conditional that validates
creation to include DT_ID (i.e., if [ -z "$M1_ID" ] || ... || [ -z "$DASH_ID" ]
|| [ -z "$DT_ID" ]), and add an echo of DT_ID in the failure block so the
downtime ID is logged alongside M1/M2/M3/DASH for debugging; adjust references
to the DT/DT_ID variables in the block to match existing naming.
---
Nitpick comments:
In
`@tests/llm/fixtures/test_ask_holmes/227_datadog_general_monitor_dashboard/test_case.yaml`:
- Around line 18-22: This multi-hop Datadog test is missing the
include_tool_calls flag, so update the test YAML to add include_tool_calls: true
at the top-level of the test definition to ensure Holmes' tool invocations (list
monitors, get monitor details, list dashboards, get dashboard details,
correlate) are validated; locate the file
test_ask_holmes/227_datadog_general_monitor_dashboard/test_case.yaml and add the
include_tool_calls: true key alongside existing keys like tags and
setup_timeout.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e993f727-4910-4cfe-a1a5-2dd3cf3944ab
📒 Files selected for processing (7)
conftest.pytests/llm/fixtures/test_ask_holmes/227_datadog_general_monitor_dashboard/test_case.yamltests/llm/fixtures/test_ask_holmes/227_datadog_general_monitor_dashboard/toolsets.yamltests/llm/fixtures/test_ask_holmes/228_datadog_general_monitor_analysis/test_case.yamltests/llm/fixtures/test_ask_holmes/228_datadog_general_monitor_analysis/toolsets.yamltests/llm/fixtures/test_ask_holmes/229_datadog_general_cross_resource/test_case.yamltests/llm/fixtures/test_ask_holmes/229_datadog_general_cross_resource/toolsets.yaml
| if [ -z "$M1_ID" ] || [ -z "$M2_ID" ] || [ -z "$M3_ID" ] || [ -z "$DASH_ID" ]; then | ||
| echo "❌ Failed to create one or more resources" | ||
| echo "M1: $M1" | ||
| echo "M2: $M2" | ||
| echo "M3: $M3" | ||
| echo "DASH: $DASH" | ||
| echo "DT: $DT" | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
Missing downtime ID validation.
The validation check verifies M1_ID, M2_ID, M3_ID, and DASH_ID but omits DT_ID. If downtime creation fails silently, the test will proceed but fail on expected outputs related to the weekly recurrence.
Proposed fix
- if [ -z "$M1_ID" ] || [ -z "$M2_ID" ] || [ -z "$M3_ID" ] || [ -z "$DASH_ID" ]; then
+ if [ -z "$M1_ID" ] || [ -z "$M2_ID" ] || [ -z "$M3_ID" ] || [ -z "$DASH_ID" ] || [ -z "$DT_ID" ]; then
echo "❌ Failed to create one or more resources"
echo "M1: $M1"
echo "M2: $M2"
echo "M3: $M3"
echo "DASH: $DASH"
echo "DT: $DT"
exit 1
fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if [ -z "$M1_ID" ] || [ -z "$M2_ID" ] || [ -z "$M3_ID" ] || [ -z "$DASH_ID" ]; then | |
| echo "❌ Failed to create one or more resources" | |
| echo "M1: $M1" | |
| echo "M2: $M2" | |
| echo "M3: $M3" | |
| echo "DASH: $DASH" | |
| echo "DT: $DT" | |
| exit 1 | |
| fi | |
| if [ -z "$M1_ID" ] || [ -z "$M2_ID" ] || [ -z "$M3_ID" ] || [ -z "$DASH_ID" ] || [ -z "$DT_ID" ]; then | |
| echo "❌ Failed to create one or more resources" | |
| echo "M1: $M1" | |
| echo "M2: $M2" | |
| echo "M3: $M3" | |
| echo "DASH: $DASH" | |
| echo "DT: $DT" | |
| exit 1 | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@tests/llm/fixtures/test_ask_holmes/229_datadog_general_cross_resource/test_case.yaml`
around lines 216 - 224, The resource validation currently checks M1_ID, M2_ID,
M3_ID, and DASH_ID but omits DT_ID; update the conditional that validates
creation to include DT_ID (i.e., if [ -z "$M1_ID" ] || ... || [ -z "$DASH_ID" ]
|| [ -z "$DT_ID" ]), and add an echo of DT_ID in the failure block so the
downtime ID is logged alongside M1/M2/M3/DASH for debugging; adjust references
to the DT/DT_ID variables in the block to match existing naming.
…on (#1947) ## Summary Fixes a silent-truncation bug in `JsonFilterMixin` that made six toolset tools produce false-negative answers (e.g. `elasticsearch_list_indices` reporting "no indices exist" against a cluster with hundreds of matching indices). Full context, reproducer, and live-cluster symptom in #1946. Root cause: when the LLM calls a mixin-backed tool with `max_depth=0` (a plausible value given the old description *"0 returns only top-level keys"*), `_truncate_to_depth` replaces the entire response with the literal string `"...truncated at depth 0"`, but `filter_result()` preserves `status=SUCCESS`. The LLM sees success + empty-looking data and confidently reports the wrong answer with no retry signal. This PR applies the minimal fix — two small edits in one file — plus regression tests: - **Rewrites the `max_depth` tool-schema description** so the LLM stops choosing 0. States the valid range (`>= 1`), points at `jq` for precise extraction, explicitly warns against `0` and negative values. - **Fail-closed in `filter_result()` on `max_depth <= 0`** with a self-corrective `ERROR` message the LLM can act on. The guard only fires when the upstream call succeeded (`status == SUCCESS`), so genuine upstream errors (e.g. HTTP 503 "cluster unreachable") are preserved verbatim — no clobbering of real failures with a parameter error. - Protects all six current consumer tools in a single mixin-level change: `elasticsearch_list_indices`, `elasticsearch_mappings`, `http_request`, `grafana_get_dashboard_by_uid`, `grafana_get_home_dashboard`, `list_prometheus_rules`. Also preemptively protects every toolset being added by #1695 (Datadog, ServiceNow, MongoDB Atlas, RabbitMQ, Coralogix, New Relic, and more) once that PR merges. ## Test plan - [x] `poetry run pytest tests/plugins/toolsets/test_json_filter_mixin.py -v --no-cov` → **9/9 passing** (4 pre-existing tests unchanged, 5 new regression tests) - [x] Standalone sanity check of `_truncate_to_depth` against an Elasticsearch `_cat/indices`–shaped payload: confirms bug at depth 0, confirms known remaining gap at depth 1 on list-of-dicts (see below), confirms real data returned at depth ≥ 2 and `None` - [x] `max_depth<=0` test: returns `ERROR` with self-corrective message - [x] `max_depth=-1` test: same (closes the undocumented negative-means-full escape hatch) - [x] Upstream-error-preservation test: when the mocked call returns `ERROR` and the LLM (hypothetically) passes `max_depth=0`, the upstream error string survives verbatim — no clobber - [x] `max_depth` omitted: full response unchanged (no regression on the happy path) - [x] Description-wording regression test: the string *"0 returns only top-level keys"* can never come back, and the description must mention `>= 1` - [ ] Maintainer to verify against a real Elasticsearch cluster using the three-step reproducer in #1946 ## Known remaining gap (deliberately out of scope — follow-up issue welcome) `max_depth=1` on a **list-of-dicts** response (the shape `_cat/indices` returns) still produces `[sentinel, sentinel, …]` with `status=SUCCESS` — the same silent-truncation class of bug, one level in. Fixing that properly requires a response-envelope redesign (e.g. `{truncated: true, max_depth_used, data, hint}`) that changes the response shape for all six consumer tools and their tests. That is a strictly larger change and deserves its own review and rollback surface, so it is deliberately out of scope here. Documented in #1946 under "Known remaining gap". ## Related PRs - #1695 extends `JsonFilterMixin` to seven additional toolsets but does **not** touch the mixin core. If it merges before this fix, every newly-covered toolset inherits the silent-truncation bug. Complementary to this PR. - #1615 improves `jq` error messaging in the same file but a different region. No behavioral overlap; any conflict is mechanical. ## References Closes #1946 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Bug Fixes** * Added runtime validation for the depth parameter; values of 0 or below now return an error with guidance instead of being processed. * **Documentation** * Updated depth parameter description to clarify that values must be >= 1; omit the parameter for a complete, untruncated response. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Sebastien Villanueva <sebastien.villanueva@gmail.com> Co-authored-by: moshemorad <moshemorad12340@gmail.com>
Summary
This PR adds JSON filtering functionality across multiple toolsets by integrating the
JsonFilterMixinclass. This allows tools to filter and transform their JSON responses based on user-provided parameters, enabling more flexible and targeted data retrieval.Key Changes
Elasticsearch Toolset:
JsonFilterMixintoElasticsearchIndexStatsandElasticsearchNodesStatsclassesJsonFilterMixin.extend_parameters()to include filtering optionsfilter_result()to responses before returning themDatadog Toolset:
JsonFilterMixintoBaseDatadogGeneralToolclassdatadog_api_getanddatadog_api_post_searchtoolsServiceNow Toolset:
JsonFilterMixintoBaseServiceNowToolclassservicenow_get_recordsandservicenow_get_recordtoolsMongoDB Atlas Toolset:
JsonFilterMixintoMongoDBAtlasBaseToolclassReturnProjectSlowQueriesandReturnEventTypeFromProjecttoolsreturn_result()methodRabbitMQ Toolset:
JsonFilterMixintoGetRabbitMQClusterStatusclassCoralogix Toolset:
JsonFilterMixintoExecuteDataPrimeQueryclassNew Relic Toolset:
JsonFilterMixintoExecuteNRQLQueryclassImplementation Details
JsonFilterMixinin addition to their base classesJsonFilterMixin.extend_parameters()which adds filtering-related parameters to existing tool parametersself.filter_result(result, params)before returning from_invoke()methodshttps://claude.ai/code/session_01K4kVdXWMnMv5ZQMntw9shn
Summary by CodeRabbit