spb/poche Public
Agent personnel 100 % on-device — SwiftUI + Apple Foundation Models + EventKit + SwiftData. Aucune API, aucun serveur.
Swift 100%
1//2// UpdateTaskTool.swift3// Poche4//5// Author: Simon-Pierre Boucher6// Contact: contact@spboucher.ai7//89import Foundation10import FoundationModels1112struct UpdateTaskTool: Tool {13 let name = "updateTask"14 let description = "Propose de modifier une tâche existante de Poche (titre, échéance, marquer faite). L'utilisateur devra confirmer."1516 @Generable17 struct Arguments {18 @Guide(description: "Mots du titre de la tâche à retrouver")19 let taskQuery: String20 @Guide(description: "Nouveau titre, seulement si l'utilisateur veut le changer")21 let newTitle: String?22 @Guide(description: "Nouvelle échéance ISO 8601, seulement si l'utilisateur veut la changer")23 let newDueDate: String?24 @Guide(description: "Vrai seulement si l'utilisateur veut marquer la tâche comme faite")25 let markDone: Bool?26 }2728 private let confirm: ConfirmCenter29 private let store: PocheStore3031 init(confirm: ConfirmCenter, store: PocheStore) {32 self.confirm = confirm33 self.store = store34 }3536 func call(arguments: Arguments) async throws -> String {37 guard let query = ToolInput.title(arguments.taskQuery) else {38 return "Erreur : précise quelle tâche modifier."39 }4041 let matches = await store.findTasks(matching: query)42 guard let task = matches.first else {43 return "Aucune tâche ne correspond à « \(query) ». Demande à l'utilisateur de préciser."44 }45 if matches.count > 1 {46 let titles = matches.prefix(3).map { "« \($0.title) »" }.joined(separator: ", ")47 return "Plusieurs tâches correspondent : \(titles). Demande à l'utilisateur laquelle modifier."48 }4950 var newDue: Date?51 if let rawDue = arguments.newDueDate, !rawDue.trimmingCharacters(in: .whitespaces).isEmpty {52 do {53 newDue = try DateResolver.resolve(iso: rawDue)54 } catch {55 return "Erreur sur l'échéance : \(error.localizedDescription)"56 }57 }5859 let newTitle = arguments.newTitle.flatMap(ToolInput.title)60 guard newTitle != nil || newDue != nil || arguments.markDone != nil else {61 return "Erreur : aucune modification demandée. Demande à l'utilisateur ce qu'il veut changer."62 }6364 let draft = TaskUpdateDraft(65 taskID: task.uuid,66 currentTitle: task.title,67 newTitle: newTitle,68 newDue: newDue,69 markDone: arguments.markDone70 )71 await confirm.propose(PendingAction(payload: .taskUpdate(draft)))7273 return "Proposition affichée : modification de la tâche « \(task.title) ». Rien n'est encore modifié — l'utilisateur doit confirmer."74 }75}76