Contents

CustomStage

A custom processing stage in a Spotlight search pipeline.

Declaration

protocol CustomStage : Generable, Decodable, Encodable, Sendable

Mentioned in

Overview

Conform your struct to this protocol to add a processing stage that the pipeline can select and execute.

Declare the payload types your stage handles via inputTypes, then implement only the typed execute overload(s) that match. The framework routes each incoming payload to the correct overload; unimplemented overloads throw fatalError by default. Stages may run in parallel — do not depend on execution order.

Use the static member lookup pattern so stages can be configured with leading dot syntax:

struct SentimentStage: CustomStage {
    static var name: String { "sentiment" }
    static var description: String { "Scores search results by sentiment" }
    static var inputTypes: [SearchPipelineDataType] { [.items] }
    static var outputTypes: [SearchPipelineDataType] { [.scoredItems] }

    var mode: String

    func execute(items: [CSSearchableItem]) async throws -> SearchPipelineData {
        let scored = items.map { item in
            ScoredSearchableItem(item: item,
                                 score: SentimentAnalyzer.score(item, mode: mode))
        }
        return .scoredItems(scored)
    }
}

extension CustomStage where Self == SentimentStage {
    static func sentiment(mode: String = "all") -> Self {
        SentimentStage(mode: mode)
    }
}

// Usage:
let tool = SpotlightSearchTool(configuration: .init(
    customStages: [.sentiment(), .sentiment(mode: "positive")]
))

Topics

Getting the stage metadata

Performing the stage behavior

See Also

Tool customization