Skip to content

feat: Adding karpenter toolsets - #1932

Open
mrinalpravi wants to merge 5 commits into
HolmesGPT:masterfrom
mrinalpravi:feat/karpenter-toolset
Open

mrinalpravi wants to merge 5 commits into
HolmesGPT:masterfrom
mrinalpravi:feat/karpenter-toolset

Conversation

@mrinalpravi

@mrinalpravi mrinalpravi commented Apr 20, 2026 •

Copy link
Copy Markdown
Contributor

Adds a new built-in karpenter/core toolset so HolmesGPT can investigate Karpenter-driven node autoscaling issues directly, alongside existing Kubernetes-ecosystem toolsets (ArgoCD, Helm, Cilium, KubeVela).

Summary by CodeRabbit

  • New Features

    • Added a Karpenter toolset with Kubernetes-focused inspection and troubleshooting tools.
  • Documentation

    • Added Karpenter docs, nav/card entry, README/integrations updates, setup guidance, config examples, and sample diagnostic queries.
  • Tests

    • Added tests validating the Karpenter toolsets’ metadata, prerequisites, parameters, and command/YAML rendering.
  • Bug Fixes

    • Improved toolset configuration override behavior to preserve intended override semantics and resolved values.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@netlify

netlify Bot commented Apr 20, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for holmes-docs ready!

Name Link
🔨 Latest commit 511d64b
🔍 Latest deploy log https://app.netlify.com/projects/holmes-docs/deploys/6a4472ed23407e0008496362
😎 Deploy Preview https://deploy-preview-1932--holmes-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Apr 20, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds Karpenter support: documentation and nav entries, a new karpenter toolset manifest with cloud-agnostic and AWS-specific kubectl-backed tools and LLM instructions, tests for the toolset, and an adjustment to Toolset.override_with plus corresponding unit tests.

Changes

Cohort / File(s) Summary
Documentation & Navigation
README.md, docs/why-holmesgpt.md, docs/data-sources/builtin-toolsets/.nav.yml, docs/data-sources/builtin-toolsets/index.md, docs/data-sources/builtin-toolsets/karpenter.md
Add Karpenter to infra/data-sources lists and nav; new detailed Karpenter docs page describing toolsets, prerequisites, configuration, examples, and usage.
Toolset Manifest
holmes/plugins/toolsets/karpenter.yaml
New toolset defining karpenter/core and karpenter/aws tools (kubectl-backed commands, CRD/provider gating, LLM instructions, and an llm_summarize transformer for controller logs).
Toolset Tests
tests/plugins/toolsets/test_karpenter_toolset.py
New pytest verifying both toolsets, metadata, exact tool inventories, prerequisites, parameter inference, Jinja command rendering, defaults, YAML output, and presence of llm_summarize.
Core logic change
holmes/core/tools.py
Modify Toolset.override_with to read explicit fields from the override (__pydantic_fields_set__) and use getattr per-field (skip name, ignore None/empty values) to preserve custom types during in-place overrides.
Override behavior tests
tests/core/test_toolset_manager.py
Extend tests to cover Toolset.override_with semantics: field-set-only overrides, falsy-value handling, skipping empty values, env substitution preservation, CallablePrerequisite handling, and end-to-end manager override flow.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Holmes as "HolmesGPT"
    participant Kubectl as kubectl
    participant K8s as "Kubernetes API"

    User->>Holmes: holmes ask (investigate pending pods)
    Holmes->>Holmes: check prerequisite CRD `nodepools.karpenter.sh`
    alt CRD missing
        Holmes-->>User: toolset disabled / notify
    else CRD present
        Holmes->>Kubectl: get pods --field-selector=status.phase=Pending
        Kubectl->>K8s: GET /api/v1/.../pods
        K8s-->>Kubectl: pending pods
        Kubectl-->>Holmes: pod list

        Holmes->>Kubectl: get nodeclaims/nodepools (CRD)
        Kubectl->>K8s: GET nodeclaims/nodepools.karpenter.sh
        K8s-->>Kubectl: nodeclaim/nodepool list
        Kubectl-->>Holmes: resources

        alt NodeClaim needs diagnosis
            Holmes->>Kubectl: describe nodeclaim <name>
            Kubectl->>K8s: DESCRIBE nodeclaim
            K8s-->>Kubectl: nodeclaim details
            Kubectl-->>Holmes: details
        end

        Holmes->>Kubectl: get disruption events & controller logs
        Kubectl->>K8s: GET events / logs
        K8s-->>Kubectl: events & logs
        Kubectl-->>Holmes: logs/events

        Holmes-->>User: aggregated diagnostics & LLM summary
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels

evals-label-logs

Suggested reviewers

  • moshemorad
  • arikalon1
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Adding karpenter toolsets' directly and accurately describes the main change: introduction of new Karpenter toolsets (both core and AWS variants) to HolmesGPT.
Docstring Coverage ✅ Passed Docstring coverage is 80.77% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
tests/plugins/toolsets/test_karpenter_toolset.py (1)

33-101: Add type hints to the new tests.

The new fixture and test functions should annotate return values and the fixture parameter.

Proposed typing update
 from holmes.plugins.toolsets import load_toolsets_from_file
+from holmes.core.tools import Toolset
@@
 `@pytest.fixture`(scope="module")
-def karpenter_toolset():
+def karpenter_toolset() -> Toolset:
@@
-def test_karpenter_toolset_metadata(karpenter_toolset):
+def test_karpenter_toolset_metadata(karpenter_toolset: Toolset) -> None:
@@
-def test_karpenter_toolset_has_all_expected_tools(karpenter_toolset):
+def test_karpenter_toolset_has_all_expected_tools(karpenter_toolset: Toolset) -> None:
@@
-def test_karpenter_toolset_prerequisites(karpenter_toolset):
+def test_karpenter_toolset_prerequisites(karpenter_toolset: Toolset) -> None:
@@
-def test_karpenter_tool_parameters_are_inferred(karpenter_toolset):
+def test_karpenter_tool_parameters_are_inferred(karpenter_toolset: Toolset) -> None:
@@
-def test_karpenter_commands_render_with_params(karpenter_toolset):
+def test_karpenter_commands_render_with_params(karpenter_toolset: Toolset) -> None:

As per coding guidelines, "Type hints are required throughout the codebase (mypy configuration in pyproject.toml)."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/plugins/toolsets/test_karpenter_toolset.py` around lines 33 - 101,
Update the new tests to include type annotations: annotate the karpenter_toolset
fixture return type (e.g., -> Toolset or the actual toolset class used by
load_toolsets_from_file) and annotate the test function parameters to accept
that fixture (karpenter_toolset: Toolset) and all test functions to return None
(e.g., def test_karpenter_toolset_metadata(karpenter_toolset: Toolset) -> None).
Ensure imports include the Toolset type or typing.Any if the concrete type is
unavailable, and reference load_toolsets_from_file, KARPENTER_YAML, and the
fixture name karpenter_toolset when applying the annotations.
docs/data-sources/builtin-toolsets/karpenter.md (1)

3-3: Avoid listing toolset capabilities in the intro.

This enumerates specific diagnostic capabilities that can become stale as tools evolve. Keep the intro generic and let users discover capabilities through Holmes.

Proposed wording
-This toolset lets HolmesGPT investigate [Karpenter](https://karpenter.sh/) node autoscaling — why pods stay `Pending`, why a `NodeClaim` never becomes a real `Node`, and why Karpenter is disrupting (consolidating, expiring, drifting) nodes you didn't expect.
+Use this toolset to connect HolmesGPT with [Karpenter](https://karpenter.sh/) for node autoscaling investigations.

As per coding guidelines, "docs/data-sources/builtin-toolsets/**/*.md: Don't list what a toolset/integration can do in documentation - users discover capabilities by using Holmes, and feature lists become stale quickly."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/data-sources/builtin-toolsets/karpenter.md` at line 3, The intro
sentence beginning "This toolset lets HolmesGPT investigate Karpenter node
autoscaling — why pods stay `Pending`, why a `NodeClaim` never becomes a real
`Node`, and why Karpenter is disrupting (consolidating, expiring, drifting)
nodes you didn't expect." enumerates capabilities and should be replaced with a
short, generic description; remove the specific diagnostic examples and any
capability list, and instead use a single-line, high-level intro that says the
doc describes the Karpenter toolset for HolmesGPT without listing what it can do
so the content won't become stale (locate and edit the intro paragraph in
karpenter.md where that sentence appears).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/data-sources/builtin-toolsets/karpenter.md`:
- Around line 37-55: Replace the five separate fenced code blocks with a single
fenced bash block that contains all five holmes ask commands in order (the lines
starting with holmes ask "Why are my pending pods...", holmes ask "I have a
NodeClaim stuck in Unknown...", holmes ask "Which NodePool would satisfy...",
holmes ask "Why did Karpenter terminate node ip-10-0-12-34.ec2.internal earlier
today?", and holmes ask "Is my EC2NodeClass default picking up the correct
subnets and security groups?"), removing the repeated ```bash fences so the
commands are consolidated into one code block.

In `@holmes/plugins/toolsets/karpenter.yaml`:
- Around line 68-70: The command string in the karpenter_disruption_events entry
uses an invalid multi-value field selector (reason=Disrupted,DisruptionBlocked);
update the command for the "karpenter_disruption_events" item to remove the
--field-selector portion and rely on --sort-by=.lastTimestamp (or perform
client-side filtering after retrieving events) so kubectl get events -A
--sort-by=.lastTimestamp is used instead of the current invalid selector.

In `@README.md`:
- Line 63: Add a Karpenter-specific logo under images/integration_logos (e.g.,
karpenter-icon.png) and update the README row that currently references
images/integration_logos/kubernetes-icon.png to use the new
images/integration_logos/karpenter-icon.png (the markdown line containing the
Karpenter link and Kubernetes img tag). Also ensure the new asset name is used
consistently in other docs mentioned in the comment
(docs/walkthrough/why-holmesgpt.md, docs/data-sources/builtin-toolsets/index.md,
and docs/data-sources/builtin-toolsets/{karpenter}.md) so the integration
displays the Karpenter logo everywhere.

---

Nitpick comments:
In `@docs/data-sources/builtin-toolsets/karpenter.md`:
- Line 3: The intro sentence beginning "This toolset lets HolmesGPT investigate
Karpenter node autoscaling — why pods stay `Pending`, why a `NodeClaim` never
becomes a real `Node`, and why Karpenter is disrupting (consolidating, expiring,
drifting) nodes you didn't expect." enumerates capabilities and should be
replaced with a short, generic description; remove the specific diagnostic
examples and any capability list, and instead use a single-line, high-level
intro that says the doc describes the Karpenter toolset for HolmesGPT without
listing what it can do so the content won't become stale (locate and edit the
intro paragraph in karpenter.md where that sentence appears).

In `@tests/plugins/toolsets/test_karpenter_toolset.py`:
- Around line 33-101: Update the new tests to include type annotations: annotate
the karpenter_toolset fixture return type (e.g., -> Toolset or the actual
toolset class used by load_toolsets_from_file) and annotate the test function
parameters to accept that fixture (karpenter_toolset: Toolset) and all test
functions to return None (e.g., def
test_karpenter_toolset_metadata(karpenter_toolset: Toolset) -> None). Ensure
imports include the Toolset type or typing.Any if the concrete type is
unavailable, and reference load_toolsets_from_file, KARPENTER_YAML, and the
fixture name karpenter_toolset when applying the annotations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 341bf78a-b6c0-44ee-9f82-3838e38ee0f4

📥 Commits

Reviewing files that changed from the base of the PR and between b24a252 and fbe6b1c539ecee5b1b80f60cd41b81231316effb.

📒 Files selected for processing (7)
  • README.md
  • docs/data-sources/builtin-toolsets/.nav.yml
  • docs/data-sources/builtin-toolsets/index.md
  • docs/data-sources/builtin-toolsets/karpenter.md
  • docs/why-holmesgpt.md
  • holmes/plugins/toolsets/karpenter.yaml
  • tests/plugins/toolsets/test_karpenter_toolset.py

Comment thread docs/data-sources/builtin-toolsets/karpenter.md
Comment thread holmes/plugins/toolsets/karpenter.yaml Outdated
Comment thread README.md Outdated
@AllaniAnirudh

Copy link
Copy Markdown

Thanks for picking this up, @mrinalpravi, this implements the proposal I filed in #1923. Glad to see it moving so quickly. The YAML follows the argocd.yaml template cleanly and the
llm_instructions troubleshooting workflow is well-thought-out.

A few substantive suggestions from someone who's been scoping this for a few days. Happy to open inline review comments if the maintainers want them broken out:

  1. karpenter_controller_logs hardcodes -n kube-system. The official Karpenter Helm chart installs into its own karpenter namespace by default (see karpenter.sh/docs/getting-started).
    kube-system is unusual for production installs. Suggest making the namespace a parameter with a sensible default, e.g. {{ namespace | default("karpenter") }}, or using -A -l
    app.kubernetes.io/name=karpenter to be namespace-agnostic.

  2. Consider adding llm_summarize transformer on karpenter_controller_logs. Karpenter controller logs are extremely noisy (reconcile loops, launch decisions, drift checks). kubernetes.yaml
    already uses llm_summarize on similarly noisy tools — it keeps the context window healthy for follow-up reasoning. Relevant to the token-consumption concerns in the recent compaction work
    (Add cached tokens tracking to LLM usage reporting #1680, Add conversation history compaction start event and enhance compaction metrics #1768).

  3. Prerequisite only checks the karpenter.sh CRD. Six of the nine tools depend on ec2nodeclasses.karpenter.k8s.aws. On AKS/GKE clusters, the karpenter.sh CRDs exist but ec2nodeclasses won't,
    so the toolset enables and then half the tools fail at call-time. Suggest adding kubectl get crd ec2nodeclasses.karpenter.k8s.aws as a second prerequisite, or splitting into karpenter/core
    and karpenter/aws sub-toolsets so Azure/GCP can be added later without disabling the whole thing.

  4. karpenter_disruption_events field selector may miss events. reason=Disrupted,DisruptionBlocked covers the common cases but Karpenter also emits Unconsolidatable, FailedDraining, and
    DisruptionWaitingReadiness in recent releases. Could be worth widening or dropping the field selector in favor of a namespace/label scope.

  5. Missing karpenter_nodeclaim_get. You have _describe which is human-readable, but LLMs often reason better on raw -o yaml. Small addition, mirrors the _get/_describe split already used on
    NodePools.

  6. Docstring coverage. CodeRabbit's pre-merge check is warning 0% — worth adding a module docstring to the test file and a short one on each test function.

Provider extensibility (Azure AKSNodeClass, GCP) is a natural follow-up I'm happy to pick up as a separate PR once this lands. Also flagging #1802 (toolset config rework) as potentially
requiring a rebase depending on land order.

Again, nice work — looking forward to this shipping.

@moshemorad
moshemorad self-requested a review April 21, 2026 07:13
@moshemorad

Copy link
Copy Markdown
Collaborator

@claude review

Comment thread holmes/plugins/toolsets/karpenter.yaml
Comment thread holmes/plugins/toolsets/karpenter.yaml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
docs/data-sources/builtin-toolsets/karpenter.md (1)

7-8: Consider simplifying the toolset descriptions.

Lines 7-8 enumerate specific tools and resources in detail, which could become stale as the toolsets evolve. Consider simplifying to conceptual descriptions that explain the split without listing specific features:

-- **`karpenter/core`** — cloud-agnostic tools: NodePools, NodeClaims, disruption events, controller logs, pending pods. Works on any cluster running upstream Karpenter (AWS, Azure, GCP, on-prem).
-- **`karpenter/aws`** — AWS-specific tools for inspecting `EC2NodeClass` resources (AMI selectors, subnets, security groups, IAM instance profile, userdata). Requires the Karpenter AWS provider CRDs.
+- **`karpenter/core`** — cloud-agnostic Karpenter resources and diagnostics. Works on any cluster running upstream Karpenter (AWS, Azure, GCP, on-prem).
+- **`karpenter/aws`** — AWS-specific infrastructure inspection via EC2NodeClass. Requires the Karpenter AWS provider CRDs.

As per coding guidelines, "Don't list what a toolset/integration can do in documentation - users discover capabilities by using Holmes, and feature lists become stale quickly."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/data-sources/builtin-toolsets/karpenter.md` around lines 7 - 8, Replace
the detailed feature lists for the karpenter toolsets with concise conceptual
descriptions: update the "karpenter/core" entry to say it provides
cloud-agnostic Karpenter observability (e.g., node lifecycle, disruption and
controller diagnostics) without enumerating specific resources, and update
"karpenter/aws" to note it contains AWS-specific extensions (provider CRD
integrations and AWS-related configuration) without listing AMI selectors,
subnets, security groups, or other concrete fields; keep references to the split
between core and AWS provider but remove the fragile feature-itemization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/data-sources/builtin-toolsets/karpenter.md`:
- Around line 7-8: Replace the detailed feature lists for the karpenter toolsets
with concise conceptual descriptions: update the "karpenter/core" entry to say
it provides cloud-agnostic Karpenter observability (e.g., node lifecycle,
disruption and controller diagnostics) without enumerating specific resources,
and update "karpenter/aws" to note it contains AWS-specific extensions (provider
CRD integrations and AWS-related configuration) without listing AMI selectors,
subnets, security groups, or other concrete fields; keep references to the split
between core and AWS provider but remove the fragile feature-itemization.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d24c02aa-edd2-4fe8-88af-d8177234273d

📥 Commits

Reviewing files that changed from the base of the PR and between fbe6b1c539ecee5b1b80f60cd41b81231316effb and 9e1d7c685d8987f5d04009c5cb4b3ce33c6b28db.

⛔ Files ignored due to path filters (1)
  • images/integration_logos/karpenter-icon.png is excluded by !**/*.png
📒 Files selected for processing (4)
  • README.md
  • docs/data-sources/builtin-toolsets/karpenter.md
  • holmes/plugins/toolsets/karpenter.yaml
  • tests/plugins/toolsets/test_karpenter_toolset.py
✅ Files skipped from review due to trivial changes (2)
  • README.md
  • tests/plugins/toolsets/test_karpenter_toolset.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • holmes/plugins/toolsets/karpenter.yaml

@mrinalpravi

Copy link
Copy Markdown
Contributor Author

Hi @AllaniAnirudh, Thanks for the detailed review

I've addressed the review comments:

  • Split into karpenter/core + karpenter/aws (fixes the AKS/GKE silent-failure)
  • Parameterized the controller-logs namespace via ns (note: namespace is reserved in Jinja2)
  • Added llm_summarize on controller logs, widened the disruption-events filter, added karpenter_nodeclaim_get and test docstrings
  • Verified live on an EKS cluster with core CRDs but no AWS provider — core enables, aws gates off cleanly

cc - @moshemorad

@mrinalpravi

Copy link
Copy Markdown
Contributor Author

Unit test
image
Verified live on an EKS cluster
image

@AllaniAnirudh

Copy link
Copy Markdown

Thanks @mrinalpravi for the quick turnaround, pulled d9898c6 and walked through the diff. The split into karpenter/core + karpenter/aws with separate CRD prerequisites cleanly resolves the AKS/GKE silent-failure, the ns
parameter is well-chosen (appreciate the inline explanation about namespace being reserved in Jinja2, both in the docs and the test docstring), and llm_summarize on the controller logs is the right call given
how chatty the reconcile loop is. karpenter_nodeclaim_get alongside _describe is a nice addition for when the raw spec is what you actually need.

A few small, non-blocking nits if you want to polish further:

  1. Icon source — you added images/integration_logos/karpenter-icon.png (used by the README and docs index) but both toolsets' icon_url still point at
    raw.githubusercontent.com/kubernetes-sigs/karpenter/.../full-logo.png. Either the local PNG is unused, or icon_url should reference it for consistency with other toolsets.
  2. tags: [core] on karpenter/aws — since this toolset is AWS-gated, the core tag reads a bit misleadingly. Worth checking how aks/gcp toolsets are tagged for precedent.
  3. karpenter_disruption_events — kubectl get events -A has no time window, so on busy clusters the grep can still return a lot. A --sort-by=.lastTimestamp plus a tail (or kubectl events --for where available)
    would bound the output.
  4. Render test coverage for karpenter/aws — test_karpenter_commands_render_with_params only exercises core tools. A one-liner asserting karpenter_ec2nodeclass_get renders correctly with {"name": "..."} would
    round out the suite.
  5. Test path construction — os.path.join(file, "..", "..", ...) works, but pathlib.Path(file).resolve().parents[3] / "holmes/plugins/toolsets/karpenter.yaml" is easier to read. Purely cosmetic.

Nice work overall, the live EKS verification is reassuring.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/core/test_toolset_manager.py (1)

579-719: Add type annotations to the new tests.

The new helper is annotated, but the added test functions still need -> None; fixture parameters like tmp_path and monkeypatch should also be typed where used.

As per coding guidelines, **/*.py: Type hints are required throughout the codebase (mypy configuration in pyproject.toml).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/core/test_toolset_manager.py` around lines 579 - 719, All new test
functions need explicit return type annotations and fixture parameter types: add
"-> None" to each test (e.g. test_override_with_copies_set_fields,
test_override_with_does_not_override_name,
test_override_with_enabled_false_propagates,
test_override_with_does_not_touch_unset_fields,
test_override_with_skips_empty_values,
test_override_with_preserves_env_var_resolution_from_yaml_file,
test_override_with_handles_toolset_with_callable_prerequisites,
test_override_with_full_flow_through_toolset_manager) and annotate fixtures
where used (e.g. tmp_path: Path, monkeypatch: pytest.MonkeyPatch); also ensure
you import Path from pathlib and pytest (or the MonkeyPatch type) at the top of
the test file so the annotations resolve for mypy.
🤖 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/core/test_toolset_manager.py`:
- Around line 646-675: The test
test_override_with_preserves_env_var_resolution_from_yaml_file uses a fixture
key named "secret" which triggers Ruff S105 (hardcoded secret) — change the YAML
key name (and any other occurrences in the nearby test block at ~698-719) from
"secret" to a neutral name like "placeholder" or "token", update all references
in the test (e.g., target.config["secret"] -> target.config["placeholder"]) and
in the written YAML content so the env-var substitution logic in ToolsetManager
and override_with remains the same but the linter no longer flags it.
- Around line 567-719: Add an integration-style test fixture that actually
exercises the Karpenter toolsets (karpenter/core and karpenter/aws) end-to-end:
create a new test under tests/llm/fixtures (following
tests/llm/fixtures/test_ask_holmes/ or test_holmes_checks/) which writes a
custom toolsets.yaml enabling the karpenter toolsets, instantiates
ToolsetManager with that file, loads the toolsets (use
manager._list_all_toolsets(check_prerequisites=False) or the existing ask_holmes
harness), and drives an LLM query that triggers Karpenter diagnostic tools;
assert that rendered tool invocations and returned outputs match expected
realistic patterns (e.g., NodePool/NodeClaim inspection, disruption events).
Mock the LLM/backend where needed to return deterministic responses and
reference the toolset names 'karpenter/core' and 'karpenter/aws' and the
ToolsetManager symbol to locate integration points.

---

Nitpick comments:
In `@tests/core/test_toolset_manager.py`:
- Around line 579-719: All new test functions need explicit return type
annotations and fixture parameter types: add "-> None" to each test (e.g.
test_override_with_copies_set_fields, test_override_with_does_not_override_name,
test_override_with_enabled_false_propagates,
test_override_with_does_not_touch_unset_fields,
test_override_with_skips_empty_values,
test_override_with_preserves_env_var_resolution_from_yaml_file,
test_override_with_handles_toolset_with_callable_prerequisites,
test_override_with_full_flow_through_toolset_manager) and annotate fixtures
where used (e.g. tmp_path: Path, monkeypatch: pytest.MonkeyPatch); also ensure
you import Path from pathlib and pytest (or the MonkeyPatch type) at the top of
the test file so the annotations resolve for mypy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2faa7f7f-bdd8-46ae-8ba8-c55117aae94b

📥 Commits

Reviewing files that changed from the base of the PR and between d9898c6199b845a1572c831980092c3db8ee0415 and d5100a3e96163f090ea47038c2b1ee9585955e0e.

📒 Files selected for processing (2)
  • holmes/core/tools.py
  • tests/core/test_toolset_manager.py

Comment thread tests/core/test_toolset_manager.py
Comment thread tests/core/test_toolset_manager.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@holmes/plugins/toolsets/karpenter.yaml`:
- Around line 1-2: Add integration tests alongside
tests/plugins/toolsets/test_karpenter_toolset.py that run against a real cluster
(use a pytest marker like `@pytest.mark.integration`) to validate prerequisite
gating and runtime behavior: implement checks that query the cluster for the
NodePool CRD when exercising karpenter/core and for the EC2NodeClass CRD when
exercising karpenter/aws (skip the test with a clear message if the CRD is
absent), then execute at least one real command path which invokes kubectl (or
the same command wrapper used by the toolset code) against an actual Karpenter
cluster and assert success; reference the existing test file name and the
toolset identifiers karpenter/core and karpenter/aws to locate where to add
these integration cases.
- Around line 64-66: The pipeline in the karpenter_disruption_events command
masks upstream failures; update the command string for the
karpenter_disruption_events entry so the shell runs with pipefail enabled (e.g.,
use bash -o pipefail -c "<pipeline>") so that if kubectl fails due to RBAC/API
errors the whole pipeline exits non‑zero; locate the karpenter_disruption_events
block and replace the raw pipeline in the command value with a bash -o pipefail
invocation wrapping the existing kubectl | grep | tail pipeline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3f54cd15-da9d-4994-b393-c64d128c4feb

📥 Commits

Reviewing files that changed from the base of the PR and between d5100a3e96163f090ea47038c2b1ee9585955e0e and f28f3f70955244a106becc1684109b8ddffd7fb4.

📒 Files selected for processing (2)
  • holmes/plugins/toolsets/karpenter.yaml
  • tests/plugins/toolsets/test_karpenter_toolset.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/plugins/toolsets/test_karpenter_toolset.py

Comment thread holmes/plugins/toolsets/karpenter.yaml
Comment thread holmes/plugins/toolsets/karpenter.yaml
  Adds the karpenter/core and karpenter/aws toolsets for investigating
  Karpenter node autoscaling (NodePools, NodeClaims, disruption events,
  controller logs, EC2NodeClass inspection).

  Includes:
  - holmes/plugins/toolsets/karpenter.yaml
  - tests/plugins/toolsets/test_karpenter_toolset.py (YAML loader unit tests)
  - tests/core/test_toolset_manager.py (ToolsetManager integration tests)
  - docs/data-sources/builtin-toolsets/karpenter.md
  - images/integration_logos/karpenter-icon.png

Signed-off-by: mrinalpravi <mrinalpr1998@gmail.com>
@mrinalpravi
mrinalpravi force-pushed the feat/karpenter-toolset branch from 42d7c48 to 1b67831 Compare April 23, 2026 11:06
@mrinalpravi

Copy link
Copy Markdown
Contributor Author

Hi @AllaniAnirudh , Thanks for the review.

Addressed the review comments

  • icon_url on both toolsets now references the committed karpenter-icon.png
    via the HolmesGPT/holmesgpt raw URL (consistent with README/docs)
  • karpenter/aws tag changed from core -> cli, following aks.yaml precedent
    for cloud-provider-gated toolsets
  • karpenter_disruption_events bounded via tail -n {{ lines | default(100) }}
    to cap output on busy clusters
  • added render test for karpenter_ec2nodeclass_get and disruption_events
    lines parameter
  • test fixture path migrated from os.path.join to pathlib"

@mrinalpravi

Copy link
Copy Markdown
Contributor Author

Hi @moshemorad , this PR has been in open state for 2 months.

Could you please review when you get a chance.

Thanks!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants