UAT: Anonymous/inline tools in skill YAML restricted to source: custom only — spec requires same schema as named tools #2999

Open
opened 2026-04-05 03:26:31 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/skill-inline-tool-schema-source-types
  • Commit Message: fix(skills): expand SkillInlineToolSchema to support all named-tool source types
  • Milestone: v3.7.0
  • Parent Epic: #393

Bug Report

What Was Tested

The SkillInlineToolSchema class in src/cleveragents/skills/schema.py and the Anonymous Tool definition from the specification.

Expected Behavior (from spec)

The specification (Glossary, §Tools & Skills) defines:

Anonymous Tool: An inline tool definition embedded in a skill YAML or actor graph node. Same schema as a named tool but unregistered, unnamespaced, and scoped only to its defining context.

"Same schema as a named tool" means anonymous tools should support all the same source types as named tools: mcp, agent_skill, builtin, custom, and wrapped.

Actual Behavior (from code analysis)

The SkillInlineToolSchema in src/cleveragents/skills/schema.py has a source field validator that rejects anything other than "custom":

class SkillInlineToolSchema(BaseModel):
    source: str = Field(
        ...,
        description="Source type. Must be 'custom' for inline tools.",
    )
    code: str = Field(
        ...,
        min_length=1,
        description="Python code defining the tool's behavior.",
    )

    @field_validator("source")
    @classmethod
    def validate_source(cls, v: str) -> str:
        """Validate that source is 'custom'."""
        if v != "custom":
            raise ValueError(
                f"Invalid inline tool source '{v}'. "
                "Inline tools must have source: custom."
            )
        return v

This means a skill YAML cannot define an anonymous tool that references an MCP server or Agent Skills folder inline. The spec says anonymous tools have the "same schema as a named tool," which includes all source types.

Example of Rejected (but spec-valid) YAML

name: local/my-skill
inline_tools:
  - name: github-search
    source: mcp
    mcp_server: github
    mcp_tool_name: search_repos
    description: Search GitHub repositories

This would be rejected with "Inline tools must have source: custom."

Code Location

  • src/cleveragents/skills/schema.py, SkillInlineToolSchema.validate_source() — rejects non-custom sources
  • src/cleveragents/skills/schema.py, SkillInlineToolSchema.code — marked as required, but should be optional for non-custom sources

Fix Required

Update SkillInlineToolSchema to accept all source types supported by named tools (mcp, agent_skill, builtin, custom, wrapped), with appropriate conditional field requirements:

  • source: customcode required
  • source: mcpmcp_server and mcp_tool_name required
  • source: agent_skillagent_skill_path required
  • etc.

Severity

Medium — limits the expressiveness of skill YAML files. Skill authors cannot define inline MCP or Agent Skills tools, forcing them to register all non-custom tools separately before referencing them.

Subtasks

  • Write a failing BDD scenario (Behave/Gherkin) in features/ that reproduces the rejection of a spec-valid source: mcp inline tool definition
  • Write failing BDD scenarios for each additional source type: agent_skill, builtin, wrapped
  • Remove the validate_source validator that hard-codes source: custom in SkillInlineToolSchema
  • Expand SkillInlineToolSchema to include all source-type-specific fields (mcp_server, mcp_tool_name, agent_skill_path, etc.) as optional fields
  • Add a model_validator (or equivalent) to enforce conditional field requirements per source type (e.g., code required only when source: custom)
  • Update the code field to be optional (Optional[str]) with appropriate validation logic
  • Ensure SkillInlineToolSchema passes nox -e typecheck with no # type: ignore suppressions
  • Update any existing unit tests that assumed source: custom is the only valid value
  • Run nox -e unit_tests and nox -e coverage_report to confirm ≥ 97% coverage

Definition of Done

  • A failing BDD test reproducing the bug exists before any implementation changes
  • SkillInlineToolSchema accepts all five source types: mcp, agent_skill, builtin, custom, wrapped
  • Conditional field validation is enforced per source type (e.g., code required only for custom)
  • All existing skill schema tests continue to pass
  • nox -e typecheck passes with zero errors and no suppression comments
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/skill-inline-tool-schema-source-types` - **Commit Message**: `fix(skills): expand SkillInlineToolSchema to support all named-tool source types` - **Milestone**: v3.7.0 - **Parent Epic**: #393 ## Bug Report ### What Was Tested The `SkillInlineToolSchema` class in `src/cleveragents/skills/schema.py` and the Anonymous Tool definition from the specification. ### Expected Behavior (from spec) The specification (Glossary, §Tools & Skills) defines: > **Anonymous Tool**: An inline tool definition embedded in a skill YAML or actor graph node. **Same schema as a named tool** but unregistered, unnamespaced, and scoped only to its defining context. "Same schema as a named tool" means anonymous tools should support all the same `source` types as named tools: `mcp`, `agent_skill`, `builtin`, `custom`, and `wrapped`. ### Actual Behavior (from code analysis) The `SkillInlineToolSchema` in `src/cleveragents/skills/schema.py` has a `source` field validator that rejects anything other than `"custom"`: ```python class SkillInlineToolSchema(BaseModel): source: str = Field( ..., description="Source type. Must be 'custom' for inline tools.", ) code: str = Field( ..., min_length=1, description="Python code defining the tool's behavior.", ) @field_validator("source") @classmethod def validate_source(cls, v: str) -> str: """Validate that source is 'custom'.""" if v != "custom": raise ValueError( f"Invalid inline tool source '{v}'. " "Inline tools must have source: custom." ) return v ``` This means a skill YAML cannot define an anonymous tool that references an MCP server or Agent Skills folder inline. The spec says anonymous tools have the "same schema as a named tool," which includes all source types. ### Example of Rejected (but spec-valid) YAML ```yaml name: local/my-skill inline_tools: - name: github-search source: mcp mcp_server: github mcp_tool_name: search_repos description: Search GitHub repositories ``` This would be rejected with "Inline tools must have source: custom." ### Code Location - `src/cleveragents/skills/schema.py`, `SkillInlineToolSchema.validate_source()` — rejects non-custom sources - `src/cleveragents/skills/schema.py`, `SkillInlineToolSchema.code` — marked as required, but should be optional for non-custom sources ### Fix Required Update `SkillInlineToolSchema` to accept all source types supported by named tools (`mcp`, `agent_skill`, `builtin`, `custom`, `wrapped`), with appropriate conditional field requirements: - `source: custom` → `code` required - `source: mcp` → `mcp_server` and `mcp_tool_name` required - `source: agent_skill` → `agent_skill_path` required - etc. ### Severity Medium — limits the expressiveness of skill YAML files. Skill authors cannot define inline MCP or Agent Skills tools, forcing them to register all non-custom tools separately before referencing them. ## Subtasks - [ ] Write a failing BDD scenario (Behave/Gherkin) in `features/` that reproduces the rejection of a spec-valid `source: mcp` inline tool definition - [ ] Write failing BDD scenarios for each additional source type: `agent_skill`, `builtin`, `wrapped` - [ ] Remove the `validate_source` validator that hard-codes `source: custom` in `SkillInlineToolSchema` - [ ] Expand `SkillInlineToolSchema` to include all source-type-specific fields (`mcp_server`, `mcp_tool_name`, `agent_skill_path`, etc.) as optional fields - [ ] Add a `model_validator` (or equivalent) to enforce conditional field requirements per source type (e.g., `code` required only when `source: custom`) - [ ] Update the `code` field to be optional (`Optional[str]`) with appropriate validation logic - [ ] Ensure `SkillInlineToolSchema` passes `nox -e typecheck` with no `# type: ignore` suppressions - [ ] Update any existing unit tests that assumed `source: custom` is the only valid value - [ ] Run `nox -e unit_tests` and `nox -e coverage_report` to confirm ≥ 97% coverage ## Definition of Done - [ ] A failing BDD test reproducing the bug exists before any implementation changes - [ ] `SkillInlineToolSchema` accepts all five source types: `mcp`, `agent_skill`, `builtin`, `custom`, `wrapped` - [ ] Conditional field validation is enforced per source type (e.g., `code` required only for `custom`) - [ ] All existing skill schema tests continue to pass - [ ] `nox -e typecheck` passes with zero errors and no suppression comments - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-05 03:27:43 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Confirmed
  • MoSCoW: Should Have

Valid finding verified during batch triage.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Confirmed - **MoSCoW**: Should Have Valid finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#393 Epic: Skill & Tool Lifecycle
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2999
No description provided.