Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add tool description to tool start event #880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
moshemorad wants to merge 2 commits into master
base: master
Choose a base branch
Loading
from ROB-1963-add-params-description-to-tool-start

Conversation

Copy link
Contributor

@moshemorad moshemorad commented Aug 20, 2025

No description provided.

Copy link
Contributor

coderabbitai bot commented Aug 20, 2025
edited
Loading

Walkthrough

Adds tool-specific metadata to START_TOOL events in the streaming path (call_stream) by parsing tool arguments, resolving the tool, computing a parameterized description, and including params and description in the emitted stream payload. No changes to invocation, error handling, or non-streaming logic.

Changes

Cohort / File(s) Summary of Changes
Streaming START_TOOL enrichment
holmes/core/tool_calling_llm.py
In call_stream, parse tool arguments to params, resolve tool, compute description via get_parameterized_one_liner, and include params and description in START_TOOL event payload alongside tool_name and id. Purely additive to streaming data.

Sequence Diagram(s)

sequenceDiagram
 autonumber
 participant L as LLM
 participant O as Orchestrator (call_stream)
 participant R as ToolRegistry
 participant S as StreamSink
 participant T as ToolExecutor
 L->>O: Emit tool calls (name, id, arguments)
 loop For each tool call
 O->>O: Parse arguments -> tool_params (json)
 O->>R: Resolve tool by name
 R-->>O: Tool reference
 O->>O: Compute description via get_parameterized_one_liner(tool_params)
 O-->>S: START_TOOL {id, tool_name, params, description}
 O->>T: Schedule/execute tool
 T-->>O: Tool result/stream
 O-->>S: TOOL_OUTPUT / END_TOOL
 end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ROB-1963-add-params-description-to-tool-start

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (2)
holmes/core/tool_calling_llm.py (2)

701-715: Optional: DRY parsing/description logic with _invoke_tool

The new argument parsing and description resolution duplicates logic in _invoke_tool (exception handling, hasattr checks). Consider extracting a small helper (e.g., _extract_tool_metadata(tool_call) -> tuple[name, params_dict, description_str]) and reuse in both places to avoid divergence.

I can draft this helper and wire it in both call_stream and _invoke_tool if you want.


710-715: Consider redacting params before streaming for security

You now emit raw params on START_TOOL. If params may contain tokens, secrets, or PII, this increases exposure surface. You already sanitize for description via get_parameterized_one_liner; consider applying similar sanitization to the streamed params (or feature-flag it).

If sanitize_params is available from holmes.core.tools, you could apply it here before yielding.

Would you like me to add opt-in redaction (e.g., via a settings flag) and wire sanitize_params here?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a9bf9e8 and 1c9ae81.

📒 Files selected for processing (1)
  • holmes/core/tool_calling_llm.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.py: ALWAYS place Python imports at the top of the file, not inside functions or methods
Type hints are required (project is type-checked with mypy)
Use Ruff for formatting and linting (configured in pyproject.toml)

Files:

  • holmes/core/tool_calling_llm.py
🧬 Code Graph Analysis (1)
holmes/core/tool_calling_llm.py (3)
holmes/core/tools_utils/tool_executor.py (1)
  • get_tool_by_name (60-64)
holmes/core/tools.py (2)
  • get_parameterized_one_liner (178-179)
  • get_parameterized_one_liner (205-212)
holmes/utils/stream.py (2)
  • StreamMessage (18-20)
  • StreamEvents (10-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Pre-commit checks
  • GitHub Check: llm_evals
  • GitHub Check: Pre-commit checks
🔇 Additional comments (1)
holmes/core/tool_calling_llm.py (1)

710-715: Verify downstream consumers handle new fields and possible None description

We’ve added two new keys—params and description—to the START_TOOL event payload in holmes/core/tool_calling_llm.py (lines 709–715). A quick search didn’t reveal any in-repo consumers of StreamEvents.START_TOOL, so it’s unclear whether UI components, analytics pipelines or other downstream handlers expect a fixed schema or non-null description.

Please manually verify that all consumers of this event:

  • Properly deserialize the new params field
  • Safely handle a null/None description

Comment on lines +701 to +707
tool_params = (
json.loads(t.function.arguments) if t.function.arguments else {}
)
tool = self.tool_executor.get_tool_by_name(t.function.name)
description = (
tool.get_parameterized_one_liner(tool_params) if tool else None
)
Copy link
Contributor

@coderabbitai coderabbitai bot Aug 20, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Guard against invalid JSON and custom tool calls in streaming path

Two issues:

  • json.loads on t.function.arguments is unguarded and can raise, breaking streaming.
  • Assumes t.function exists; custom tool calls (non-function) will raise AttributeError. _invoke_tool correctly guards via hasattr; mirror that here.

Apply this safer parsing and resolution:

- tool_params = (
- json.loads(t.function.arguments) if t.function.arguments else {}
- )
- tool = self.tool_executor.get_tool_by_name(t.function.name)
- description = (
- tool.get_parameterized_one_liner(tool_params) if tool else None
- )
+ tool_name = None
+ tool_params = None
+ description = None
+ if hasattr(t, "function"):
+ tool_name = t.function.name
+ args_str = getattr(t.function, "arguments", None)
+ if args_str:
+ try:
+ parsed = json.loads(args_str)
+ tool_params = parsed if isinstance(parsed, dict) else {}
+ except Exception:
+ logging.warning(
+ f"Failed to parse arguments for tool: {tool_name}. args: {args_str}"
+ )
+ tool_params = {}
+ tool_obj = self.tool_executor.get_tool_by_name(tool_name)
+ if tool_obj:
+ try:
+ description = tool_obj.get_parameterized_one_liner(tool_params or {})
+ except Exception:
+ logging.exception(
+ f"Failed to compute parameterized description for tool: {tool_name}"
+ )
+ else:
+ logging.error(f"Unsupported custom tool call: {t}")
+ tool_name = "unknown"
📝 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.

Suggested change
tool_params = (
json.loads(t.function.arguments) if t.function.arguments else {}
)
tool = self.tool_executor.get_tool_by_name(t.function.name)
description = (
tool.get_parameterized_one_liner(tool_params) if tool else None
)
tool_name = None
tool_params = None
description = None
if hasattr(t, "function"):
tool_name = t.function.name
args_str = getattr(t.function, "arguments", None)
if args_str:
try:
parsed = json.loads(args_str)
tool_params = parsed if isinstance(parsed, dict) else {}
except Exception:
logging.warning(
f"Failed to parse arguments for tool: {tool_name}. args: {args_str}"
)
tool_params = {}
tool_obj = self.tool_executor.get_tool_by_name(tool_name)
if tool_obj:
try:
description = tool_obj.get_parameterized_one_liner(tool_params or {})
except Exception:
logging.exception(
f"Failed to compute parameterized description for tool: {tool_name}"
)
else:
logging.error(f"Unsupported custom tool call: {t}")
tool_name = "unknown"

Comment on lines +710 to +715
data={
"tool_name": t.function.name,
"id": t.id,
"params": tool_params,
"description": description,
},
Copy link
Contributor

@coderabbitai coderabbitai bot Aug 20, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use computed tool_name and normalized params in START_TOOL payload

Follow-up to the parsing fix: rely on the precomputed variables and avoid direct t.function access. Also normalize params to a dict to keep payload shape stable.

- data={
- "tool_name": t.function.name,
- "id": t.id,
- "params": tool_params,
- "description": description,
- },
+ data={
+ "tool_name": tool_name,
+ "id": t.id,
+ "params": tool_params or {},
+ "description": description,
+ },
📝 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.

Suggested change
data={
"tool_name": t.function.name,
"id": t.id,
"params": tool_params,
"description": description,
},
data={
"tool_name": tool_name,
"id": t.id,
"params": tool_paramsor {},
"description": description,
},
🤖 Prompt for AI Agents
In holmes/core/tool_calling_llm.py around lines 710 to 715, the START_TOOL
payload is using t.function.name and raw tool_params directly; update it to use
the precomputed tool_name variable and a normalized params dict (e.g., ensure
params are converted/validated to a plain dict called normalized_params) so the
payload shape stays stable; replace "tool_name": t.function.name with
"tool_name": tool_name and "params": tool_params with "params":
normalized_params (or ensure tool_params is normalized to a dict before use).

Copy link
Contributor

Results of HolmesGPT evals

  • ask_holmes: 34/39 test cases were successful, 1 regressions, 2 skipped, 2 setup failures
Test suite Test case Status
ask 01_how_many_pods
ask 02_what_is_wrong_with_pod
ask 03_what_is_the_command_to_port_forward
ask 04_related_k8s_events ↪️
ask 05_image_version
ask 09_crashpod
ask 10_image_pull_backoff
ask 11_init_containers
ask 14_pending_resources
ask 15_failed_readiness_probe
ask 17_oom_kill
ask 18_crash_looping_v2
ask 19_detect_missing_app_details
ask 20_long_log_file_search
ask 24_misconfigured_pvc
ask 28_permissions_error 🚧
ask 29_events_from_alert_manager ↪️
ask 39_failed_toolset
ask 41_setup_argo
ask 42_dns_issues_steps_new_tools
ask 43_current_datetime_from_prompt
ask 45_fetch_deployment_logs_simple
ask 51_logs_summarize_errors
ask 53_logs_find_term
ask 54_not_truncated_when_getting_pods
ask 59_label_based_counting
ask 60_count_less_than 🚧
ask 61_exact_match_counting
ask 63_fetch_error_logs_no_errors
ask 79_configmap_mount_issue
ask 83_secret_not_found
ask 86_configmap_like_but_secret
ask 93_calling_datadog
ask 93_calling_datadog
ask 93_calling_datadog
ask 97_logs_clarification_needed
ask 110_k8s_events_image_pull
ask 24a_misconfigured_pvc_basic
ask 13a_pending_node_selector_basic

Legend

  • ✅ the test was successful
  • ↪️ the test was skipped
  • ⚠️ the test failed but is known to be flaky or known to fail
  • 🚧 the test had a setup failure (not a code regression)
  • 🔧 the test failed due to mock data issues (not a code regression)
  • ❌ the test failed and should be fixed before merging the PR

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

Reviewers

@coderabbitai coderabbitai[bot] coderabbitai[bot] left review comments

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /