Skip to content

[Feat]: Gemini adapter polish — sanitization tests, doc template, optional catalog lint #230

Description

@rosspeili

Feature Description

Follow-up polish after #223 / PR #229 (to_gemini_tool() returns types.Tool with sanitized names). Core fix and required doc updates land in that PR; this issue tracks regression prevention and contributor guidance so Gemini snippets do not drift back.

Scope

  1. Test coverage — extend tests/test_loader.py:

    • Assert finance/wallet_screeningfinance_wallet_screening in to_gemini_tool() output
    • Assert return type is google.genai.types.Tool (not dict)
  2. Contributor docs — short additions:

    • docs/usage/gemini.md — one paragraph on dispatch: match function_call.name to sanitized name (SkillLoader._sanitize_function_tool_name(manifest["name"])) or adapter-derived name
    • docs/usage/skill_usage_template.md — same rule for new skill catalog Gemini blocks
  3. CHANGELOG hygiene — if Fix: to_gemini_tool to return types.Tool object. Fixes #223 #229 only lists under Fixed, add Changed bullet noting to_gemini_tool() return type change (dicttypes.Tool) for programmatic callers

  4. Guardrail — extend tests/test_registry_docs.py or add tests/test_skill_docs_gemini.py to fail when docs/skills/*.md Gemini sections contain:

    • tool_decl["name"] / gemini_decl["name"] mutation
    • types.Tool(function_declarations=[ manual wrap after to_gemini_tool()
    • function_call.name == bundle["manifest"]["name"] without sanitize (registry IDs with /)

Out of scope

Rationale

#229 fixes the bug and aligns examples; without guardrails, catalog pages and copy-paste snippets can regress (we already had manual types.Tool workarounds in three skill docs). A sanitization test is cheap insurance. An optional markdown lint catches the same failure mode #178 addresses for examples, but for docs/skills/ where agents copy integration code verbatim.

Implementation Idea

Phase 1 (minimal — good first issue)

Add to test_to_gemini_tool:

dummy_bundle = {
    "manifest": {
        "name": "finance/wallet_screening",
        "parameters": {"type": "object", "properties": {}},
    }
}
tool = SkillLoader.to_gemini_tool(dummy_bundle)
assert tool.function_declarations[0].name == "finance_wallet_screening"

Update gemini.md + skill_usage_template.md with canonical dispatch one-liner.

Phase 2

Parametrize over docs/skills/*.md (exclude README); regex or simple string checks for anti-patterns listed above. Grandfather none after #229 doc pass is merged.

Acceptance

Metadata

Metadata

Assignees

No one assigned

    Labels

    core frameworkChanges to loader, env, base classes, or model adapters.documentationImprovements or additions to documentation.enhancementNew feature or request.good first issueGood for newcomers.

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions