Skip to main content

Module submit_tool

Module submit_tool 

Source
Expand description

DynamicSubmitTool — Provider-native structured output via tool injection

Implements rig’s ToolDyn trait with a runtime JSON schema as parameters. When injected into an AgentBuilder, the LLM is forced to call submit_result({...}) matching the schema, giving provider-side enforcement.

This is Layer 0 of Nika’s structured output defense system.

§How it works

The “Extractor pattern” from rig creates a synthetic tool whose parameters field IS the target JSON schema. Combined with tool_choice: Required, the LLM provider enforces schema compliance server-side (~90%+ first-attempt success). The tool’s call() simply passes through the arguments — the schema enforcement already happened at the provider level.

Unlike rig’s built-in Extractor (which requires compile-time Rust types via #[derive(JsonSchema)]), DynamicSubmitTool accepts runtime serde_json::Value schemas from YAML workflow definitions.

§Example

use nika::runtime::DynamicSubmitTool;
use rig::tool::ToolDyn;

let schema = serde_json::json!({
    "type": "object",
    "properties": { "name": { "type": "string" } },
    "required": ["name"]
});
let tool = DynamicSubmitTool::new(schema);
let agent = AgentBuilder::new(model)
    .tools(vec![Box::new(tool) as Box<dyn ToolDyn>])
    .tool_choice(ToolChoice::Required)
    .build();

Structs§

DynamicSubmitTool
A synthetic tool that forces the LLM to produce structured JSON output.