Skip to content

Skills (and bash) tool never reach Gemini — agentsToTools called without nativeTools #32

@mepsd

Description

@mepsd

Summary

The Gemini planner builds SkillsTool and BashTool and stores them on the planner struct, but the call to agentsToTools in process() never passes them as nativeTools. As a result, the function
declarations for activate_skill / run_skill_script / bash never appear in the Gemini request. Skills are silently invisible to the model even when skills_dir is set correctly.

Repro

ax.yaml:

server:
  address: ":8494"
eventlog:
  sqlite:
    filename: "eventlog/log.sqlite"
planner:
  gemini:
    model: "gemini-2.5-pro"
    timeout: "60s"
    skills_dir: "./skills"

Skill at ./skills/lowercase/SKILL.md + ./skills/lowercase/scripts/lowercase.sh (copied verbatim from examples/skills/lowercase).

ax serve
ax exec --server localhost:8494 --input "lowercase: HELLO WORLD"

Expected

Gemini receives activate_skill and run_skill_script as available tools; planner emits a function call; skill script runs; lowercased text returned.

Actual

Two failure modes depending on model:

  • gemini-2.5-pro400 INVALID_ARGUMENT: Function calling config is set without function_declarations.
    Because ToolConfig is always set (with FunctionCallingConfigModeAuto), but Tools ends up empty when no remote agents are registered.

  • gemini-3.5-flashMALFORMED_FUNCTION_CALL (no content in candidates).
    The model sees skills described in the appended system prompt (from SkillsTool.SystemPrompt()) and tries to call a function that wasn't declared, so it produces a malformed tool call.

In neither case does the skill ever execute.

Root cause

internal/gemini/gemini_planner.go:198:

tools, err := agentsToTools(p.registry)

agentsToTools signature (line 516):

func agentsToTools(registry AgentRegistry, nativeTools ...Tool) ([]*genai.Tool, error)

The variadic nativeTools is the intended channel for native tools (skills, bash). But the call site passes only the registry. p.skillsTool (constructed at line 127 and shown to have a working FuncDecl() at
gemini.go:347) is never wired into the request.

The only other call site (gemini_planner_test.go) has the same shape, so it's not covered by tests either.

Suggested fix

tools, err := agentsToTools(p.registry, p.skillsTool, p.bashTool)

Add a planner test that asserts at least the skills tool function declarations appear in the generated GenerateContentConfig.Tools when skills_dir resolves to a non-empty directory.

Environment

  • AX: go install github.com/google/ax/cmd/ax@latest (built from main)
  • Go: 1.26.2 darwin/arm64
  • macOS 15 (Darwin 25.5.0)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions