Context
core/specials.rs currently defines:
History — schemars-derived placeholder
ToolCall — schemars-derived placeholder (name-collides with rig::message::ToolCall)
NoTool / NoToolError — rig::Tool impl placeholder
These are features, not dead code — History and Tools are important for the DSPy programming model. But they're wired to the old schemars plumbing, not the BamlType/Facet/SignatureSchema typed path.
DSPy Python has:
dspy.Tool — wraps Python functions, auto-extracts name + args schema from type hints
dspy.ToolCalls — output field type for tool call results
list[dspy.Tool] as an input field type recognized by the Adapter
- Native function calling detection: if model supports it, tools go via LM API; otherwise formatted in prompt text
What's needed
Migrate types to BamlType + Facet
History → #[derive(BamlType, Facet)] instead of #[derive(Serialize, JsonSchema)]
ToolCall → rename to avoid collision with rig's ToolCall, derive BamlType + Facet
- These should be recognizable as special field types in
SignatureSchema
Adapter-level tool awareness
- ChatAdapter should detect
Tool/ToolCalls fields in a signature
- If model supports native function calling → route via LM API tools
- Otherwise → format tool descriptions in prompt text (like DSPy's fallback)
Wire NoTool properly
- Or remove it if rig's tool abstraction is sufficient
- Current
NoTool is a rig::Tool impl that returns "No tool" — placeholder
Post-schemars
- Once this + field!/sign! macros are migrated,
schemars dep can be dropped
Related
Context
core/specials.rscurrently defines:History— schemars-derived placeholderToolCall— schemars-derived placeholder (name-collides withrig::message::ToolCall)NoTool/NoToolError— rig::Tool impl placeholderThese are features, not dead code — History and Tools are important for the DSPy programming model. But they're wired to the old schemars plumbing, not the BamlType/Facet/SignatureSchema typed path.
DSPy Python has:
dspy.Tool— wraps Python functions, auto-extracts name + args schema from type hintsdspy.ToolCalls— output field type for tool call resultslist[dspy.Tool]as an input field type recognized by the AdapterWhat's needed
Migrate types to BamlType + Facet
History→#[derive(BamlType, Facet)]instead of#[derive(Serialize, JsonSchema)]ToolCall→ rename to avoid collision with rig'sToolCall, derive BamlType + FacetSignatureSchemaAdapter-level tool awareness
Tool/ToolCallsfields in a signatureWire NoTool properly
NoToolis a rig::Tool impl that returns "No tool" — placeholderPost-schemars
schemarsdep can be droppedRelated