← All courses ← Course home

Lesson 03 of 05

Resume after a retry or relaunch

Load the checkpoint, build a new session, restore the transcript when you can, and run only the first unfinished step.

Agent brief (llms.md)

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.

Load fileCheckpoint
New sessionEmpty at first
RestoreTranscript, then next step
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
}
plan != nilDo not call the model
Missing fieldRun that step
SaveThen advance step

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.

Rule. Create a new session. Restore data. Never assume the old object is still in memory.

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.