Skip to content

feat(tools): add Hlido agent trust tools (trust check + recommend)#6554

Open
ankitkapur1992-hlido wants to merge 1 commit into
crewAIInc:mainfrom
ankitkapur1992-hlido:hlido_trust_tool
Open

feat(tools): add Hlido agent trust tools (trust check + recommend)#6554
ankitkapur1992-hlido wants to merge 1 commit into
crewAIInc:mainfrom
ankitkapur1992-hlido:hlido_trust_tool

Conversation

@ankitkapur1992-hlido

Copy link
Copy Markdown

What

Adds two CrewAI tools under lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/ that let a crew vet other AI agents against independent, evidence-backed reviews before delegating work to them:

  • HlidoTrustCheckTool — given an agent slug (e.g. aider), returns its Hlido score (0-100), tier (VITAL/STEADY/FADING/FLATLINE), a PASS/FAIL gate against a min_score, and the reviewed strengths / red flags.
  • HlidoRecommendTool — given a free-text need (e.g. "AI coding agent"), returns matching reviewed agents ranked by trust score.

Why

Agents increasingly delegate to other agents/tools with no independent signal of reliability. These tools give a routing/orchestration agent a machine-readable trust check at decision time — a natural fit for CrewAI's delegation model.

Notes

  • No API key required — both tools call the public Hlido API (hlido.eu).
  • No new dependencies — uses requests (already a CrewAI dependency).
  • Pydantic args_schema, graceful error strings (no exceptions leaking to the agent), README, and mocked unit tests (no network).
  • Registered in crewai_tools/tools/__init__.py and crewai_tools/__init__.py; tool.specs.json regenerated (only the two new entries added).
  • uv run pytest tests/tools/hlido_trust_tool_test.py — 8 passed; black/isort clean.

Disclosure

I'm the founder of Hlido. This integration is opt-in, uses only the public Hlido API, and adds no new dependencies. Happy to adjust naming/placement to match maintainer preferences.

…ecommendTool)

Two tools that let a crew vet other AI agents against Hlido's independent,
evidence-backed reviews before delegating to them:

- HlidoTrustCheckTool: score/tier/PASS-FAIL verdict for a known agent slug
- HlidoRecommendTool: find a reviewed agent for a free-text need, ranked by score

Both use the public Hlido API (no API key) and add no new dependencies.
Includes README, mocked unit tests, and tool.specs.json entries.
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds HlidoTrustCheckTool and HlidoRecommendTool, exposing them through CrewAI packages and tool specifications. The tools query Hlido public APIs, return trust or recommendation JSON, document their inputs, and include mocked unit coverage.

Changes

Hlido tool runtime

Layer / File(s) Summary
Hlido tool runtime
lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/hlido_trust_tool.py
Defines typed inputs, score tiers, trust scorecard checks, recommendation filtering and ranking, API error handling, and JSON-formatted results.

Public exports and specifications

Layer / File(s) Summary
Public exports and tool specifications
lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/__init__.py, lib/crewai-tools/src/crewai_tools/tools/__init__.py, lib/crewai-tools/src/crewai_tools/__init__.py, lib/crewai-tools/tool.specs.json
Re-exports both tools and adds their initialization and run schemas to the tool specifications.
Hlido usage documentation
lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/README.md
Documents installation, usage, inputs, public API endpoints, and string-based error responses.

Runtime behavior tests

Layer / File(s) Summary
Runtime behavior tests
lib/crewai-tools/tests/tools/hlido_trust_tool_test.py
Covers tier mapping, trust-check pass/fail behavior, validation and 404 handling, recommendation ranking, filtering, and empty results.

Sequence Diagram(s)

sequenceDiagram
  participant CrewAI
  participant HlidoTools
  participant HlidoAPI
  CrewAI->>HlidoTools: Run trust check or recommendation
  HlidoTools->>HlidoAPI: Request scorecard or review registry
  HlidoAPI-->>HlidoTools: Return review data or error
  HlidoTools-->>CrewAI: Return verdict or ranked JSON results
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding Hlido agent trust tools.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new tools, tests, docs, and registration.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Choose a reason for hiding this comment

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

🧹 Nitpick comments (5)
lib/crewai-tools/tests/tools/hlido_trust_tool_test.py (2)

114-116: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Avoid ValueError to ensure a clear AssertionError on test failure.

Using .index() will raise a ValueError if the substring is not found in result, which disrupts standard test runner tracebacks. Using .find() ensures the test fails with a cleaner AssertionError instead.

💡 Proposed refactor
-    assert result.index('"slug": "b"') < result.index('"slug": "a"')
-    assert '"slug": "d"' not in result
-    assert '"slug": "c"' not in result
+    pos_b = result.find('"slug": "b"')
+    pos_a = result.find('"slug": "a"')
+    assert pos_b != -1 and pos_a != -1
+    assert pos_b < pos_a
+    assert '"slug": "d"' not in result
+    assert '"slug": "c"' not in result
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/tests/tools/hlido_trust_tool_test.py` around lines 114 -
116, Update the ordering assertion in the relevant test to use non-throwing
substring position checks instead of str.index, so missing slugs produce a clear
AssertionError through the assertion framework. Preserve the existing
requirement that slug “b” appears before slug “a”, while keeping the exclusions
for slugs “c” and “d”.

10-15: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Improve mock realism for HTTP errors and empty JSON lists.

Currently, raise_for_status() is mocked to return None even for error status codes (like 404), which does not reflect the actual behavior of the requests library. This could hide bugs if the underlying tool logic relies on catching HTTPError. Additionally, json_data or {} will incorrectly evaluate to {} if json_data is explicitly provided as an empty list [].

Consider updating the mock to accurately raise HTTPError on error codes and correctly handle falsy json_data inputs.

♻️ Proposed refactor
 def _mock_response(status_code=200, json_data=None):
+    import requests
     resp = MagicMock()
     resp.status_code = status_code
-    resp.json.return_value = json_data or {}
-    resp.raise_for_status.return_value = None
+    resp.json.return_value = json_data if json_data is not None else {}
+    if status_code >= 400:
+        resp.raise_for_status.side_effect = requests.exceptions.HTTPError(response=resp)
+    else:
+        resp.raise_for_status.return_value = None
     return resp
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/tests/tools/hlido_trust_tool_test.py` around lines 10 - 15,
Update the _mock_response helper to make raise_for_status raise
requests.exceptions.HTTPError for HTTP error status codes while preserving
successful responses, and replace the json_data or {} fallback with a
None-specific check so explicitly supplied empty lists remain unchanged.
lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/hlido_trust_tool.py (2)

186-188: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Prevent "None" from being injected into the searchable text.

If the Hlido API returns null for a key (e.g., "summary": null), item.get("summary", "") will return None, as the key exists. Calling str(None) turns it into the string "None", which lowercases to "none". This means the word "none" becomes part of the searchable text, potentially causing false-positive matches.

Using item.get(k) or "" cleanly falls back to an empty string for both missing keys and null values.

♻️ Proposed refactor
             haystack = " ".join(
-                str(item.get(k, "")) for k in ("name", "slug", "category", "summary")
+                str(item.get(k) or "") for k in ("name", "slug", "category", "summary")
             ).lower()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/hlido_trust_tool.py`
around lines 186 - 188, Update the searchable text construction in the Hlido
tool’s haystack expression to use an empty-string fallback for both missing and
null values before converting items to strings. Specifically adjust the item
field lookup in the join over name, slug, category, and summary so null API
fields cannot produce the literal “None”.

84-84: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

URL-encode the slug to prevent invalid URL exceptions.

Although the slug is stripped and lowercased, a user might still pass an unexpected string containing spaces or special characters (e.g., "aider agent"). Using urllib.parse.quote ensures the URL remains valid and gracefully falls back to a 404 (handled by your logic below) rather than raising an unhandled requests.exceptions.InvalidURL exception.

💡 Proposed refactor

Ensure you add import urllib.parse at the top of the file, then apply:

-        url = f"{self.base_url}/data/scorecards/{slug}.json"
+        encoded_slug = urllib.parse.quote(slug)
+        url = f"{self.base_url}/data/scorecards/{encoded_slug}.json"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/hlido_trust_tool.py`
at line 84, Update the URL construction in the HlidоTrust tool method around the
scorecard slug to URL-encode the normalized slug with urllib.parse.quote before
interpolating it into the endpoint. Add the required urllib.parse import and
preserve the existing 404 fallback handling for encoded invalid or unexpected
slugs.
lib/crewai-tools/src/crewai_tools/tools/__init__.py (1)

87-90: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Import from the package rather than the internal module.

You have correctly set up an __init__.py file inside the hlido_trust_tool directory to export HlidoRecommendTool and HlidoTrustCheckTool. It is more idiomatic to import from the package boundary instead of directly from the internal module file.

  • lib/crewai-tools/src/crewai_tools/tools/__init__.py#L87-L90: Change the import path from crewai_tools.tools.hlido_trust_tool.hlido_trust_tool to crewai_tools.tools.hlido_trust_tool.
  • lib/crewai-tools/src/crewai_tools/__init__.py#L98-L101: Apply the exact same change to import from crewai_tools.tools.hlido_trust_tool.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/src/crewai_tools/tools/__init__.py` around lines 87 - 90,
Update the HlidoRecommendTool and HlidoTrustCheckTool imports in
lib/crewai-tools/src/crewai_tools/tools/__init__.py lines 87-90 and
lib/crewai-tools/src/crewai_tools/__init__.py lines 98-101 to import from the
hlido_trust_tool package boundary rather than its internal hlido_trust_tool
module, preserving the existing exported symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/crewai-tools/src/crewai_tools/tools/__init__.py`:
- Around line 87-90: Update the HlidoRecommendTool and HlidoTrustCheckTool
imports in lib/crewai-tools/src/crewai_tools/tools/__init__.py lines 87-90 and
lib/crewai-tools/src/crewai_tools/__init__.py lines 98-101 to import from the
hlido_trust_tool package boundary rather than its internal hlido_trust_tool
module, preserving the existing exported symbols.

In
`@lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/hlido_trust_tool.py`:
- Around line 186-188: Update the searchable text construction in the Hlido
tool’s haystack expression to use an empty-string fallback for both missing and
null values before converting items to strings. Specifically adjust the item
field lookup in the join over name, slug, category, and summary so null API
fields cannot produce the literal “None”.
- Line 84: Update the URL construction in the HlidоTrust tool method around the
scorecard slug to URL-encode the normalized slug with urllib.parse.quote before
interpolating it into the endpoint. Add the required urllib.parse import and
preserve the existing 404 fallback handling for encoded invalid or unexpected
slugs.

In `@lib/crewai-tools/tests/tools/hlido_trust_tool_test.py`:
- Around line 114-116: Update the ordering assertion in the relevant test to use
non-throwing substring position checks instead of str.index, so missing slugs
produce a clear AssertionError through the assertion framework. Preserve the
existing requirement that slug “b” appears before slug “a”, while keeping the
exclusions for slugs “c” and “d”.
- Around line 10-15: Update the _mock_response helper to make raise_for_status
raise requests.exceptions.HTTPError for HTTP error status codes while preserving
successful responses, and replace the json_data or {} fallback with a
None-specific check so explicitly supplied empty lists remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 11906207-e113-47e2-b90d-a8a7bd28b7ee

📥 Commits

Reviewing files that changed from the base of the PR and between da9902d and 6fa529a.

📒 Files selected for processing (7)
  • lib/crewai-tools/src/crewai_tools/__init__.py
  • lib/crewai-tools/src/crewai_tools/tools/__init__.py
  • lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/README.md
  • lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/__init__.py
  • lib/crewai-tools/src/crewai_tools/tools/hlido_trust_tool/hlido_trust_tool.py
  • lib/crewai-tools/tests/tools/hlido_trust_tool_test.py
  • lib/crewai-tools/tool.specs.json

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.

1 participant