Resume means: load the checkpoint, skip finished steps, create a new LanguageModelSession, and put the saved transcript back when the SDK lets you. Do this only while isResponding is false. Mutating a live response is a programmer error. Apple documents that in WWDC26 session 242.
func resume(store: CheckpointStore) async throws -> WorkflowCheckpoint {
guard var checkpoint = try await store.load() else {
throw WorkflowError.nothingToResume
}
let session = LanguageModelSession(
model: SystemLanguageModel.default,
instructions: "Continue the saved workflow. Do not restart finished steps."
)
if let data = checkpoint.transcriptData {
session.transcript = try decodeTranscript(data)
}
switch checkpoint.step {
case .plan:
checkpoint = try await runPlan(session: session, checkpoint: checkpoint)
case .gather:
checkpoint = try await runGather(session: session, checkpoint: checkpoint)
case .decide:
checkpoint = try await runDecide(session: session, checkpoint: checkpoint)
case .act:
checkpoint = try await runAct(checkpoint: checkpoint)
case .done:
break
}
try await store.save(checkpoint)
return checkpoint
}
decodeTranscript is your adapter around the installed Transcript type. If restore fails, fall back to the saved plan and gathered strings and start a clean session with those as instructions. That is worse context, but it does not redo paid or slow tool work.
func runPlan(session: LanguageModelSession, checkpoint: WorkflowCheckpoint) async throws -> WorkflowCheckpoint {
var next = checkpoint
if next.plan == nil {
let reply = try await session.respond(to: checkpoint.userPrompt)
next.plan = reply.content
next.transcriptData = try encodeTranscript(session.transcript)
next.step = .gather
next.updatedAt = .now
}
return next
}
Read Make several agents agree first, Talk to tools with MCP, and Stop prompt attacks and leaks if resume must also restore a vote gate or a redacted prompt.
Next, hook backgrounding so you save before the OS suspends you.
Key concepts
- Resume loads the checkpoint, skips finished steps, and creates a new session.
- Do not mutate transcript during a live response.
- Skip steps where outputs such as plan already exist.
- Fall back to saved plan and gathered strings if transcript decode fails.
Takeaways
- Create a new session. Restore data. Never assume the old object is still in memory.
- Skip work you already have in checkpoint fields.
- Confirm Transcript encode and decode APIs in the Xcode 27 SDK.