Skip to content

feat: extract and publish tool metadata to AMP#4298

Open
thiagomoretto wants to merge 11 commits intomainfrom
tm-push-custom-tool-metadata
Open

feat: extract and publish tool metadata to AMP#4298
thiagomoretto wants to merge 11 commits intomainfrom
tm-push-custom-tool-metadata

Conversation

@thiagomoretto
Copy link
Copy Markdown
Contributor

@thiagomoretto thiagomoretto commented Jan 28, 2026

Summary

  • Extracts rich metadata from tool classes during crewai tool publish
  • Sends metadata to AMP backend for enhanced tool discoverability
  • Displays preview of detected tools before publishing

What's Included

Tool Metadata Extraction

Automatically extracts from BaseTool classes:

  • Tool name and description
  • Init parameters schema (custom Pydantic fields)
  • Run parameters schema (from args_schema)
  • Environment variables (name, description, required, default)

Publish Preview

Shows detected tools during publish with:

  • Tool name and description
  • Init parameters with types and defaults
  • Required environment variables
image

Non-blocking Errors

Metadata extraction failures show warnings but don't block publishing.

Payload Structure

{
  "tools_metadata": {
    "tools": [
      {
        "name": "ToolClassName",
        "humanized_name": "tool_name",
        "description": "Tool description",
        "run_params_schema": { },
        "init_params_schema": { },
        "env_vars": [
          {"name": "API_KEY", "description": "...", "required": true, "default": null}
        ]
      }
    ]
  }
}

Note

Medium Risk
Adds dynamic module importing and Pydantic schema introspection during crewai tool publish, which could surface edge-case import side effects or schema-generation failures (though publish continues without metadata). Backend payload shape also changes by adding tools_metadata, requiring server compatibility.

Overview
crewai tool publish now extracts rich metadata for exported BaseTool classes (name/description, module, JSON schemas for run/init params, and env var definitions), prints a pre-publish preview, and sends this metadata to the Enterprise/AMP API as a new tools_metadata payload.

Internally, tool discovery utilities were extended with safer temporary module loading/cleanup and schema generation that omits non-JSON-serializable defaults; publish now treats metadata extraction errors as warnings and continues. Tests were updated/added to cover the new API parameter, preview/continue behavior, and metadata extraction edge cases.

Written by Cursor Bugbot for commit 6f3cfb8. This will update automatically on new commits. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open for 45 days with no activity.

@thiagomoretto thiagomoretto force-pushed the tm-push-custom-tool-metadata branch from bc6de7b to 3002211 Compare March 25, 2026 21:27
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

- Use `is not None` instead of truthiness check so empty tools list
  is sent to the API rather than being silently dropped as None
- Strip __init__ suffix from module path for tools in __init__.py files
- Extend _unwrap_schema to handle function-before, function-wrap, and
  definitions wrapper types
When env_vars uses default_factory, pydantic stores a callable in the
schema instead of a static default value. Fall back to calling the
factory when no static default is present.
Copy link
Copy Markdown
Contributor

@iris-clawd iris-clawd left a comment

Choose a reason for hiding this comment

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

PR Review: feat: extract and publish tool metadata to AMP

Overall: Solid feature — clean implementation, good test coverage, and the non-blocking error handling is the right call. A few things worth addressing before merge:


Issues

1. Empty metadata still sends payload to API
In plus_api.py, the condition is if tools_metadata is not None, so when metadata extraction fails and tools_metadata = [], the API receives {"package": "handle", "tools": []}. Consider using if tools_metadata instead (falsy check) to avoid sending an empty wrapper object — or confirm the backend handles this gracefully.

2. _extract_field_default return type looseness
The function returns str | list[Any] | int, and humanized_name passes the result through without str() wrapping (unlike description which does str(...).strip()). If a field default is unexpectedly an int or list, humanized_name in the payload would have the wrong type. Consider normalizing:

"humanized_name": str(_extract_field_default(fields.get("name"), fallback=tool_class.__name__)),

3. _unwrap_schema has no loop guard
The while loop could theoretically spin if a malformed schema has circular type references. A simple max_depth counter (e.g., 20 iterations) would make it defensive:

for _ in range(20):
    if result.get("type") not in {...}:
        break
    ...

Minor / Nits

  • SystemExit(1) change on L134 (was bare SystemExit) — good improvement, but it is a behavior change for anyone catching SystemExit by code. Intentional?
  • Test lines are long in test_main.py — the return_value dicts in @patch decorators are 150+ chars. Consider moving them to module-level constants for readability.
  • The _IGNORED_INIT_PARAMS frozenset is a nice touch for maintainability.

What looks good ✅

  • Context manager pattern for module loading with hash-based names (no more temp_module collisions)
  • Non-blocking metadata extraction — warnings only, publish continues
  • Preview output before publishing
  • Comprehensive test suite covering edge cases (empty project, import errors, syntax errors, multiple files, non-tool exports)
  • lru_cache on _get_schema_generator

Verdict: Approve with minor fixes (items 1-3 above). None are blockers but would improve robustness.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants