Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 15 additions & 19 deletions parsers/v1/src/tool_calling/structural_tag/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ use super::triggered_tags::{self, TriggeredTagsConfig};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "snake_case")]
pub enum StructuralTagSchemaMode {
/// Real schema only for tools with `strict: true`; others get an
/// unconstrained schema (`true` in xgrammar).
/// Use the declared schema unless the tool explicitly sets `strict: false`.
/// An omitted `strict` field is schema-enforced; explicit `false` uses an
/// unconstrained argument schema (`true` in xgrammar).
#[default]
Auto,
/// Real parameter schema for all tools regardless of `strict` flag.
/// Use the declared parameter schema for all tools, overriding
/// `strict: false`.
Strict,
}

Expand Down Expand Up @@ -82,33 +84,27 @@ pub(crate) fn resolve_tools_to_include<'a>(
}
}

/// Resolve one tool's argument schema using Dynamo's generic schema policy.
/// Whether a tool's declared parameter schema should constrain its arguments.
///
/// In [`StructuralTagSchemaMode::Auto`], only `strict: true` selects the
/// declared schema. Model-native builders may intentionally follow different
/// upstream semantics and should use a model-specific policy helper.
/// [`StructuralTagSchemaMode::Auto`] treats an omitted `strict` field as
/// schema-enforced. Only an explicit `strict: false` opts out. Global strict
/// mode overrides that per-tool opt-out.
pub(crate) fn uses_declared_tool_schema(tool: &ToolDefinition, strict_schema: bool) -> bool {
Comment thread
indrajit96 marked this conversation as resolved.
Resolved
strict_schema || tool.strict != Some(false)
}

/// Resolve one tool's argument schema using Dynamo's generic schema policy.
pub(crate) fn resolve_tool_schema(tool: &ToolDefinition, strict_schema: bool) -> Value {
// xgrammar uses `true` for syntactically valid but schema-unconstrained JSON.
let default_schema = json!(true);

let use_tool_schema = strict_schema || tool.strict.unwrap_or(false);
if use_tool_schema {
if uses_declared_tool_schema(tool, strict_schema) {
tool.parameters.clone().unwrap_or(default_schema)
} else {
default_schema
}
}

/// Whether Kimi's vLLM/xgrammar-compatible format should use the declared
/// parameter schema.
///
/// Kimi treats only an explicit `strict: false` as an opt-out. An omitted
/// `strict` value therefore uses the declared schema, unlike Dynamo's generic
/// [`StructuralTagSchemaMode::Auto`] policy.
pub(crate) fn kimi_uses_declared_tool_schema(tool: &ToolDefinition, strict_schema: bool) -> bool {
strict_schema || tool.strict != Some(false)
}

/// Builder for model-family-specific tool-call structural tags.
#[derive(Debug, Clone)]
#[non_exhaustive]
Expand Down
4 changes: 2 additions & 2 deletions parsers/v1/src/tool_calling/structural_tag/kimi_k2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use serde_json::{Value, json};

use super::builder::{
ToolCallFormatBuildContext, kimi_uses_declared_tool_schema, resolve_tools_to_include,
ToolCallFormatBuildContext, resolve_tools_to_include, uses_declared_tool_schema,
};
use super::format::{
ConstStringFormat, Format, JsonSchemaFormat, JsonSchemaStyle, RegexFormat, SequenceFormat,
Expand All @@ -33,7 +33,7 @@ fn tool_schema(tool: &ToolDefinition, strict_schema: bool) -> Value {
// Match vLLM/xgrammar: use the declared parameters unless the request
// explicitly opts out with strict=false. Global strict mode overrides the
// opt-out. Xgrammar uses `true` for unconstrained but valid JSON.
if kimi_uses_declared_tool_schema(tool, strict_schema) {
if uses_declared_tool_schema(tool, strict_schema) {
tool.parameters.clone().unwrap_or_else(|| json!(true))
} else {
json!(true)
Expand Down
Loading
Loading