import Foundation import FoundationModels /// The tool the on-device model calls to look things up in the user's library. /// It is the bridge between `LanguageModelSession` (generation) and the /// Spotlight index (retrieval) — together they form on-device RAG over the /// private bookmark corpus. struct BookmarkSearchTool: Tool { let name = "searchBookmarks" let description = """ Search the user's saved bookmarks. Returns the most relevant bookmarks with \ their title, website, description, and URL. Call this for any question about \ what the user has saved, read, or wants to find again. """ @Generable struct Arguments { @Guide(description: "Keywords or a short phrase describing what to look for in the saved bookmarks") var query: String } func call(arguments: Arguments) async throws -> String { Log.tool.info("searchBookmarks invoked query=\(arguments.query, privacy: .public)") let hits = await SpotlightBookmarkSearch.run(query: arguments.query, limit: 8) Log.tool.info("searchBookmarks returned \(hits.count, privacy: .public) bookmarks") guard !hits.isEmpty else { return "No bookmarks matched \"\(arguments.query)\"." } return hits.enumerated().map { idx, b in var line = "\(idx + 1). \(b.title)" if !b.host.isEmpty { line += " — \(b.host)" } if !b.description.isEmpty { line += "\n \(b.description)" } if !b.url.isEmpty { line += "\n \(b.url)" } return line }.joined(separator: "\n") } }