← All courses ← Course home

Lesson 03 of 05

Treat tools as named transitions

A tool can ask to change mode. The orchestrator checks a table. Illegal moves fail in your code, not in the prompt.

Agent brief (llms.md)

WWDC26 samples give the model a switch-mode tool. Keep that idea, then add a gate. The tool proposes to: Mode. Your table says whether the current mode allows it.

ToolPropose next mode
TableLegal?
StateAccept or reject
let legal: [Mode: Set<Mode>] = [
    .gather: [.decide],
    .decide: [.act, .gather],
    .act: [.review],
    .review: [.done, .gather]
]

struct AdvanceModeTool: Tool {
    let state: AgentState
    let description = "Request a move to a new named mode."

    @Generable
    struct Arguments {
        let to: String
    }

    func call(arguments: Arguments) async throws -> String {
        guard let next = Mode(rawValue: arguments.to) else {
            return "Unknown mode."
        }
        let allowed = legal[state.mode, default: []]
        guard allowed.contains(next) else {
            return "Blocked: \(state.mode.rawValue) cannot go to \(next.rawValue)."
        }
        state.mode = next
        return "Now \(next.rawValue)."
    }
}

Attach this tool only in states that may change mode. Act state should expose the real work tool (save a note, start a reminder), not a free-form toolbox. Search stays in gather, using the retrieval stack or SpotlightSearchTool.

If you mark tool calling as required, give an exit. Session 242 warns that required tool loops need a stop. A FinishReviewTool that moves to done is that stop.

Reject in code. A prompt that says "please do not skip review" is not a gate.

Next, put the table and the session in one loop.

Key concepts

  • A mode-change tool proposes a next Mode. The orchestrator checks the legal table.
  • Reject illegal transitions in code, not in the prompt.
  • Attach the mode-change tool only in states that may change mode.
  • A finish tool that moves to done stops required tool loops.

Takeaways

  • Act state exposes the real work tool, not a free-form toolbox.
  • Search stays in gather via retrieval or SpotlightSearchTool.
  • The table is the contract. The model only proposes.