Skip to content

Support per-tool strict schema passthrough in defineTool #736

Description

@liuxiaopai-ai

What problem are you trying to solve?

The AI SDK supports a per-tool strict?: boolean flag for function tools, and OpenAI-compatible providers can forward it as tools[].function.strict. Eve currently has no public or compiled representation for that flag:

  • ToolDefinition / PublicToolDefinition do not expose strict.
  • InternalToolDefinition and CompiledToolDefinition do not carry it.
  • The compiled manifest schema has no strict field for tools.

As a result, an authored Eve tool cannot opt into provider-native strict tool calling. Adding strict: true behind a cast is not sufficient because the compiler/runtime boundary does not preserve the field.

Minimal API shape that is currently unavailable:

import { defineTool } from "eve/tools";
import { z } from "zod";

export default defineTool({
  description: "Get weather for a city.",
  inputSchema: z.object({ city: z.string() }),
  strict: true,
  execute({ city }) {
    return { city, temperatureC: 24 };
  },
});

This matters for providers that offer schema-constrained function calling. DeepSeek's strict tool mode, for example, requires strict: true on every function in the request and validates all submitted JSON Schemas before generation:

https://api-docs.deepseek.com/guides/tool_calls/

Without an Eve-level pass-through, applications must maintain a patch/fork, bypass Eve's harness, or give up provider-guaranteed argument conformance. This also needs to cover Eve framework tools: a provider that requires every function to be strict cannot be supported by forwarding the field only for authored tools.

This is separate from #542. That proposal makes invalid tool calls observable; this request allows providers to prevent schema-invalid arguments during generation.

Observed on [email protected]; I also inspected the published [email protected] types and manifest schema and did not find a strict-tool field.

Proposed solution

Add an optional, default-off strict?: boolean field to Eve's tool definition pipeline and preserve it unchanged through compilation and runtime assembly.

Suggested scope:

  1. Add strict?: boolean to the public and shared tool definition types.
  2. Add it to InternalToolDefinition, CompiledToolDefinition, and the compiled manifest schema/version handling.
  3. Preserve it for static authored tools, dynamic tools, extension tools, subagent tools, and authored replacements of framework tools.
  4. Forward it when Eve constructs the AI SDK function tool passed to the model.
  5. Keep undefined as the default so existing agents and providers are unchanged.
  6. Optionally expose the resolved value from eve info for debugging.

Suggested tests:

  • defineTool({ strict: true }) type-checks.
  • true, false, and undefined survive compile-manifest-runtime round trips.
  • The final AI SDK tool received by a mock language model contains the expected flag.
  • Static and dynamic authored tools behave consistently.
  • Existing tools with no strict field produce unchanged requests.

I would keep provider capability detection and schema rewriting out of this first change. Eve should faithfully carry the author's intent; the provider can reject unsupported strict schemas, and applications can add provider-specific schema linting before enabling the flag.

Alternatives considered

  • Local patch/fork of Eve: feasible, but every Eve upgrade must rebase and revalidate the compiler/runtime patch.
  • Cast strict: true through any: does not solve the compiled manifest and runtime propagation gap.
  • Call the AI SDK directly outside Eve: loses Eve's durable sessions, event stream, approvals, tools, and eval harness for that model call.
  • Rewrite application schemas without changing Eve: useful preparation, but it still cannot put strict: true on the provider request.
  • A provider-global strict option: less precise and does not match the AI SDK's current per-tool contract; it also makes mixed-provider agents harder to support safely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    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