Tutorial 01: AI Routing & Tools¶
Wintermute uses a sophisticated neural routing architecture to manage interactions with multiple LLM providers. Instead of hardcoding logic for specific models, operators interact with a Router that dispatches requests based on task tags and model availability.
1. Initializing the Router¶
The recommended way to start is using the init_router bootstrap function. This function automatically registers available providers (Bedrock, Groq, OpenAI) based on your environment variables.
from wintermute.ai.bootstrap import init_router
from wintermute.ai.use import simple_chat
# Initialize the global router with registered providers
router = init_router()
print(f"Router initialized with default provider: {router.default_provider}")
2. Simple Chat Interaction¶
The simple_chat utility provides a high-level interface for standard LLM queries. By default, it uses the primary provider configured in the router, but you can override the model for specific needs.
# Default interaction (e.g., via Bedrock/Claude)
response = simple_chat(
router,
"Identify potential entry points on a device with exposed UART and JTAG headers.",
)
print(response)
3. Tool Registry Architecture¶
Wintermute's power comes from its ability to call tools. The ToolRegistry manages local static tools, while the ToolsRuntime orchestrates execution across both local tools and dynamic backends (like MCP servers).
Here is how we define and register a hardware-specific debugging tool:
from wintermute.ai.tools_runtime import Tool, tools
def jtag_enumerate_handler(args):
"""Simulate JTAG chain enumeration using OpenOCD/UrJTAG logic."""
_interface = args.get("interface", "ft2232h")
# Real-world logic would call OpenOCD or a custom bit-banging driver
return {
"status": "success",
"taps": [
{"idcode": "0x4ba00477", "name": "Cortex-M4", "irlen": 4},
{"idcode": "0x06413041", "name": "STM32F4 Boundary Scan", "irlen": 5},
],
}
jtag_tool = Tool(
name="jtag_enumerate",
description="Enumerate JTAG chain and retrieve IDCODEs for connected TAPs",
input_schema={
"type": "object",
"properties": {
"interface": {
"type": "string",
"description": "Hardware debugger interface (e.g., jlink, ft2232h)",
}
},
"required": ["interface"],
},
output_schema={"type": "object"},
handler=jtag_enumerate_handler,
)
# Register the tool in the global registry
tools.register(jtag_tool)
print(f"Registered high-fidelity tool: {jtag_tool.name}")
4. Using the Tools Runtime¶
The ToolsRuntime is used during autonomous loops to resolve and execute requested tools.
from wintermute.ai.tools_runtime import ToolsRuntime
runtime = ToolsRuntime()
async def run_example():
# The router handles logic flow by dispatching ToolCalls to the runtime
result = await runtime.run_tool("jtag_enumerate", {"interface": "ft2232h"})
print(f"TAP Enumeration Result: {result}")
# In a notebook, we can run the async function
await run_example()