A new Instruments template for the Foundation Models framework that lets developers trace, debug, and profile on-device and server-based LLM sessions β visualizing sessions, requests, model inferences, instructions, tool calls, and token metrics on a timeline.
β’ Silent failures in agentic pipelines (e.g. a missing tool in a DynamicInstructions toolset) produce no exceptions β the Instruments tree view is the only way to spot that context was wrong
β’ Token-level metrics (Time to First Token, Tokens per Second, Total Latency) are surfaced per-inference, giving concrete data to drive prompt-shortening and streaming decisions
β’ The Instructions lane shows exactly which instruction set was active at each point in time, making it possible to verify multi-mode agentic handoffs actually occurred
Shows how to configure a DynamicInstructions session with two tools so that the Foundation Models Instrument can trace the full instruction/tool lifecycle β the exact pattern demonstrated in the WWDC session.
import SwiftUI
import FoundationModels
// MARK: - Tools
struct GenerateCraftIdeaTool: Tool {
static let name = "generateCraftIdea"
static let description = "Generates a craft project idea based on the crafter's interests."
struct Arguments: Codable {
let theme: String
}
func call(arguments: Arguments) async throws -> ToolOutput {
// In production this would call into your data layer.
return ToolOutput("Here is a craft idea based on theme: \(arguments.theme)")
}
}
struct SwitchToTutorialModeTool: Tool {
static let name = "switchToTutorialMode"
static let description = "Switches the session to tutorial generation mode for the chosen craft."
struct Arguments: Codable {
let selectedCraft: String
}
func call(arguments: Arguments) async throws -> ToolOutput {
return ToolOutput("Switching to tutorial mode for: \(arguments.selectedCraft)")
}
}
// MARK: - Dynamic Instructions
struct BrainstormDynamicInstructions: DynamicInstructions {
var instructions: Instructions {
Instructions(
"""
You are a creative craft brainstorming assistant.
Suggest ideas and use generateCraftIdea to propose projects.
When the user picks one, call switchToTutorialMode with the selected craft.
""",
// FIXED: both tools are now registered β previously only GenerateCraftIdeaTool was listed
tools: [GenerateCraftIdeaTool(), SwitchToTutorialModeTool()]
)
}
}
// MARK: - ViewModel
@MainActor
final class BrainstormViewModel: ObservableObject {
@Published var messages: [String] = []
@Published var isLoading = false
private let session = LanguageModelSession(
dynamicInstructions: BrainstormDynamicInstructions()
)
func send(_ userMessage: String) async {
isLoading = true
defer { isLoading = false }
do {
let response = try await session.respond(to: Prompt(userMessage))
messages.append("You: \(userMessage)")
messages.append("Assistant: \(response.content)")
} catch {
messages.append("Error: \(error.localizedDescription)")
}
}
}
// MARK: - View
struct BrainstormView: View {
@StateObject private var vm = BrainstormViewModel()
@State private var input = ""
var body: some View {
NavigationStack {
List(vm.messages, id: \.self) { msg in
Text(msg).font(.footnote)
}
HStack {
TextField("Ask for craft ideasβ¦", text: $input)
.textFieldStyle(.roundedBorder)
Button("Send") {
let text = input
input = ""
Task { await vm.send(text) }
}
.disabled(input.isEmpty || vm.isLoading)
}
.padding()
.navigationTitle("Craft Brainstorm")
}
}
}Instruments logging is off in production; you must profile via Product > Profile in Xcode. The template only appears in the Instruments template chooser when the FoundationModels framework is linked. Silent tool-misconfiguration failures will not throw errors at runtime β Instruments is the primary diagnostic surface for these bugs.
Logging is disabled in production builds; traces are only captured during active profiling sessions. Server-model (Private Cloud Compute) requests are also captured. Trace files may contain sensitive prompt/response data β store securely.
More iOS 27 APIs land every week.
Get notified when new capabilities are published β no noise, just signal.