iOS 27 introduces DynamicProfile and DynamicInstructions to the Foundation Models framework, enabling developers to build multi-agent app experiences where a single LanguageModelSession can switch between distinct model configurations, instructions, and tools depending on the current task phase.
• Enables true multi-agent architectures entirely within one session — swap between on-device SystemLanguageModel and PrivateCloudComputeLanguageModel per task without losing conversation context.
• DynamicInstructions and historyTransform let you manage context windows precisely, trimming or summarizing transcript entries to stay within model limits as you move between agents.
• Lifecycle modifiers (onResponse) and SessionPropertyEntry allow agents to share state and update UI reactively, making it practical to build orchestrated, multi-step AI workflows in production apps.
Demonstrates a two-phase DynamicProfile session that switches from a creative brainstorm agent (using PrivateCloudComputeLanguageModel with high temperature) to a focused tutorial agent (using SystemLanguageModel), sharing state via a custom SessionPropertyEntry.
import FoundationModels
import SwiftUI
// MARK: - Session property for storing the chosen craft idea
extension SessionPropertyValues {
@SessionPropertyEntry var chosenIdea: String? = nil
}
// MARK: - Reusable instructions component
struct BrainstormInstructions: DynamicInstructions {
var body: some DynamicInstructions {
"You are a creative craft expert. Suggest three original origami project ideas based on the user's prompt. Be imaginative."
}
}
// MARK: - Tool that hands the baton to the tutorial phase
struct SelectIdeaTool: Tool {
static let name = "selectIdea"
static let description = "Call this when the user has chosen a craft idea to get a tutorial."
struct Parameters: Encodable {
let idea: String
}
func call(arguments: Parameters, context: ToolContext) async throws -> ToolOutput {
context.session.properties.chosenIdea = arguments.idea
return ToolOutput("Idea selected: \(arguments.idea). Switching to tutorial mode.")
}
}
// MARK: - The orchestrator using DynamicProfile
@Observable
final class OrigamiOrchestrator {
enum Mode { case brainstorm, tutorial }
var mode: Mode = .brainstorm
var response: String = ""
private let session: LanguageModelSession
init() {
session = LanguageModelSession {
DynamicProfile { [self] in
switch mode {
case .brainstorm:
Model(PrivateCloudComputeLanguageModel.default)
Temperature(1.0)
BrainstormInstructions()
Tool(SelectIdeaTool())
case .tutorial:
Model(SystemLanguageModel.default)
Instructions {
"You are a precise origami instructor. Provide a clear, step-by-step tutorial."
if let idea = session.properties.chosenIdea {
"The user wants to learn: \(idea)"
}
}
}
}
.onResponse { [self] in
// Auto-advance to tutorial once an idea is chosen
if session.properties.chosenIdea != nil, mode == .brainstorm {
mode = .tutorial
}
}
}
}
func send(_ message: String) async {
do {
let result = try await session.respond(to: message)
response = result.content
} catch {
response = "Error: \(error.localizedDescription)"
}
}
}
// MARK: - SwiftUI View
struct OrigamiAssistantView: View {
@State private var orchestrator = OrigamiOrchestrator()
@State private var input = ""
var body: some View {
NavigationStack {
VStack(alignment: .leading, spacing: 16) {
Text(orchestrator.mode == .brainstorm ? "🎨 Brainstorming" : "📋 Tutorial")
.font(.headline)
.foregroundStyle(orchestrator.mode == .brainstorm ? .purple : .green)
ScrollView {
Text(orchestrator.response)
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
}
.background(.regularMaterial, in: RoundedRectangle(cornerRadius: 12))
HStack {
TextField("Ask about origami…", text: $input)
.textFieldStyle(.roundedBorder)
Button("Send") {
let msg = input
input = ""
Task { await orchestrator.send(msg) }
}
.buttonStyle(.borderedProminent)
}
}
.padding()
.navigationTitle("Origami Assistant")
}
}
}• DynamicProfile body is re-evaluated on every prompt, so avoid heavy computation or side effects directly in the profile builder. • history property mutations are lossy and global across all profiles — prefer historyTransform for profile-scoped, non-destructive trimming. • FoundationModelsUtilities is a separate open-source Swift package updated independently of the OS; pin versions carefully. • reasoningLevel is only available on server (PCC) models, not SystemLanguageModel.
PrivateCloudComputeLanguageModel requires network access and Apple Intelligence eligibility; SystemLanguageModel requires an Apple Intelligence-capable device. DynamicProfile itself is available wherever FoundationModels is supported.
More iOS 27 APIs land every week.
Get notified when new capabilities are published — no noise, just signal.