Skip to content

[BUG] Zod schema not converted to JSON Schema for Ollama provider #779

@sergiomaciel

Description

@sergiomaciel

Describe the bug

VoltAgent (versions 1.1.37 and 1.2.0) does not properly convert Zod schemas to JSON Schema when using ollama-ai-provider-v2, resulting in empty parameters being sent to Ollama models. This prevents function calling from working correctly with Ollama, while the same code works perfectly with OpenAI's GPT models.

Steps To Reproduce

1. Direct Ollama API Call (✅ Works)

First, we verified that Ollama itself works perfectly with function calling:

curl http://192.168.1.22:11434/api/chat -d '{
  "model": "llama3.2:latest",
  "messages": [{"role": "user", "content": "Busca empleado legajo 1129"}],
  "tools": [{
    "type": "function",
    "function": {
      "name": "consultar_empleados",
      "description": "Busca empleados",
      "parameters": {
        "type": "object",
        "properties": {
          "legajo": {"type": "number", "description": "Número de legajo"}
        }
      }
    }
  }]
}'

Result: ✅ Ollama correctly returns tool_calls with proper arguments:

{
  "message": {
    "tool_calls": [{
      "function": {
        "name": "consultar_empleados",
        "arguments": {"legajo": "1129"}
      }
    }]
  }
}

2. ollama-ai-provider-v2 Standalone (✅ Works)

Next, we tested ollama-ai-provider-v2 with AI SDK directly (without VoltAgent):

const { generateText } = require('ai');
const { ollama } = require('ollama-ai-provider-v2');
const { z } = require('zod');

const result = await generateText({
  model: ollama('llama3.2:latest'),
  prompt: 'Busca empleado legajo 1129',
  tools: {
    consultar_empleados: {
      description: 'Busca empleados',
      parameters: z.object({
        legajo: z.number().describe('Número de legajo')
      }),
      execute: async ({ legajo }) => {
        return { success: true, legajo };
      }
    }
  }
});

Result: ✅ Tool is called correctly with proper arguments.

BUT: When inspecting the request body sent to Ollama, we see:

{
  "tools": [{
    "function": {
      "parameters": {
        "properties": {},
        "additionalProperties": false
      }
    }
  }]
}

This suggests that ollama-ai-provider-v2 expects the schema to already be in JSON Schema format, but AI SDK's generateText might be doing some conversion internally that VoltAgent is not.

3. VoltAgent with Ollama (❌ Fails)

import { Agent, createTool } from '@voltagent/core';
import { ollama } from 'ollama-ai-provider-v2';
import { z } from 'zod';

const tool = createTool({
  name: 'consultar_empleados',
  description: 'Busca empleados',
  parameters: z.object({
    legajo: z.number().describe('Número de legajo')
  }),
  execute: async (args) => {
    console.log('Tool executed with:', args);
    return { success: true };
  }
});

const agent = new Agent({
  name: 'test-agent',
  instructions: 'You are a helpful assistant',
  model: ollama('llama3.2:latest'),
  tools: [tool]
});

const result = await agent.generateText('Busca empleado legajo 1129');

Result: ❌ Tool is NOT called. Model responds without executing the function.

Logs show:

[test-agent] 🔧 Configurando agent con tool: {
  toolName: 'consultar_empleados',
  hasParameters: true,
  parametersType: 'object',
  toolKeys: ['id', 'name', 'description', 'parameters', 'outputSchema', 'type', 'execute', ...]
}

The tool has parameters (the Zod schema), but it's not being converted to JSON Schema.

4. VoltAgent with GPT (✅ Works Perfectly)

const agent = new Agent({
  name: 'test-agent',
  instructions: 'You are a helpful assistant',
  model: openai('gpt-4o-mini'),  // Changed to GPT
  tools: [tool]  // Same tool with Zod schema
});

const result = await agent.generateText('Busca empleado legajo 1129');

Result: ✅ Tool is called correctly, employee is found, everything works perfectly.

Expected behavior

When creating a VoltAgent Agent with tools that have Zod schema parameters, the schema is not converted to JSON Schema format when sent to Ollama. This results in the Ollama model receiving empty parameter definitions, preventing it from understanding what arguments to provide when calling functions.

Expected Behavior

When using a tool with Zod parameters like:

import { createTool } from '@voltagent/core';
import { z } from 'zod';

const consultarEmpleadosTool = createTool({
  name: 'consultar_empleados',
  description: 'Busca empleados en el sistema',
  parameters: z.object({
    legajo: z.number().optional().describe('Número de legajo'),
    nombre: z.string().optional().describe('Nombre del empleado'),
  }),
  execute: async (args) => { /* ... */ }
});

const agent = new Agent({
  name: 'test-agent',
  instructions: 'You are a helpful assistant',
  model: ollama('llama3.2:latest'),
  tools: [consultarEmpleadosTool]
});

The tool definition sent to Ollama should include proper JSON Schema:

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "consultar_empleados",
      "description": "Busca empleados en el sistema",
      "parameters": {
        "type": "object",
        "properties": {
          "legajo": {
            "type": "number",
            "description": "Número de legajo"
          },
          "nombre": {
            "type": "string",
            "description": "Nombre del empleado"
          }
        }
      }
    }
  }]
}

Actual Behavior

VoltAgent sends the following to Ollama:

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "consultar_empleados",
      "description": "Busca empleados en el sistema",
      "parameters": {
        "properties": {},
        "additionalProperties": false
      }
    }
  }]
}

The properties object is empty, so the model has no information about what parameters to provide.

Packages

Additional Context

  • This affects any VoltAgent setup trying to use Ollama with function calling
  • The issue is present in both 1.1.37 and 1.2.0
  • Other local LLM providers might have the same issue if they expect JSON Schema
  • The Ollama community would benefit greatly from VoltAgent support since it's a popular local LLM solution

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions