NCAssistantTask.swift 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //
  2. // NCAssistantModel.swift
  3. // Nextcloud
  4. //
  5. // Created by Milen on 08.04.24.
  6. // Copyright © 2024 Marino Faggiana. All rights reserved.
  7. //
  8. import Foundation
  9. import NextcloudKit
  10. import SwiftUI
  11. class NCAssistantTask: ObservableObject {
  12. @Published var types: [NKTextProcessingTaskType] = []
  13. @Published var filteredTasks: [NKTextProcessingTask] = []
  14. @Published var selectedType: NKTextProcessingTaskType?
  15. @Published var selectedTask: NKTextProcessingTask?
  16. @Published var hasError: Bool = false
  17. @Published var isLoading: Bool = false
  18. private var tasks: [NKTextProcessingTask] = []
  19. private let excludedTypeIds = ["OCA\\ContextChat\\TextProcessing\\ContextChatTaskType"]
  20. private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
  21. init() {
  22. load()
  23. }
  24. func load() {
  25. loadAllTypes()
  26. }
  27. func filterTasks(ofType type: NKTextProcessingTaskType?) {
  28. if let type {
  29. self.filteredTasks = tasks.filter({ $0.type == type.id })
  30. } else {
  31. self.filteredTasks = tasks
  32. }
  33. self.filteredTasks = filteredTasks.sorted(by: { $0.completionExpectedAt ?? 0 > $1.completionExpectedAt ?? 0 })
  34. }
  35. func selectTaskType(_ type: NKTextProcessingTaskType?) {
  36. selectedType = type
  37. filterTasks(ofType: self.selectedType)
  38. }
  39. func selectTask(_ task: NKTextProcessingTask) {
  40. selectedTask = task
  41. guard let id = task.id else { return }
  42. isLoading = true
  43. NextcloudKit.shared.textProcessingGetTask(taskId: id, account: appDelegate.account) { _, task, _, error in
  44. self.isLoading = false
  45. if error != .success {
  46. self.hasError = true
  47. return
  48. }
  49. self.selectedTask = task
  50. }
  51. }
  52. func scheduleTask(input: String) {
  53. isLoading = true
  54. NextcloudKit.shared.textProcessingSchedule(input: input, typeId: selectedType?.id ?? "", identifier: "assistant", account: appDelegate.account) { _, task, _, error in
  55. self.isLoading = false
  56. if error != .success {
  57. self.hasError = true
  58. return
  59. }
  60. guard let task else { return }
  61. withAnimation {
  62. self.tasks.insert(task, at: 0)
  63. self.filteredTasks.insert(task, at: 0)
  64. }
  65. }
  66. }
  67. func deleteTask(_ task: NKTextProcessingTask) {
  68. guard let id = task.id else { return }
  69. isLoading = true
  70. NextcloudKit.shared.textProcessingDeleteTask(taskId: id, account: appDelegate.account) { _, task, _, error in
  71. self.isLoading = false
  72. if error != .success {
  73. self.hasError = true
  74. return
  75. }
  76. withAnimation {
  77. self.tasks.removeAll(where: { $0.id == task?.id })
  78. self.filteredTasks.removeAll(where: { $0.id == task?.id })
  79. }
  80. }
  81. }
  82. private func loadAllTypes() {
  83. isLoading = true
  84. NextcloudKit.shared.textProcessingGetTypes(account: appDelegate.account) { _, types, _, error in
  85. self.isLoading = false
  86. if error != .success {
  87. self.hasError = true
  88. return
  89. }
  90. guard let filteredTypes = types?.filter({ !self.excludedTypeIds.contains($0.id ?? "")}), !filteredTypes.isEmpty else { return }
  91. withAnimation {
  92. self.types = filteredTypes
  93. }
  94. if self.selectedType == nil {
  95. self.selectTaskType(filteredTypes.first)
  96. }
  97. self.loadAllTasks()
  98. }
  99. }
  100. private func loadAllTasks(appId: String = "assistant") {
  101. isLoading = true
  102. NextcloudKit.shared.textProcessingTaskList(appId: appId, account: appDelegate.account) { _, tasks, _, error in
  103. self.isLoading = false
  104. if error != .success {
  105. self.hasError = true
  106. return
  107. }
  108. guard let tasks = tasks else { return }
  109. self.tasks = tasks
  110. self.filterTasks(ofType: self.selectedType)
  111. }
  112. }
  113. }
  114. extension NCAssistantTask {
  115. public func loadDummyData() {
  116. let loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  117. var tasks: [NKTextProcessingTask] = []
  118. for index in 1...10 {
  119. tasks.append(NKTextProcessingTask(id: index, type: "OCP\\TextProcessing\\FreePromptTaskType", status: index, userId: "christine", appId: "assistant", input: loremIpsum, output: loremIpsum, identifier: "", completionExpectedAt: 1712666412))
  120. }
  121. self.types = [
  122. NKTextProcessingTaskType(id: "1", name: "Free Prompt", description: ""),
  123. NKTextProcessingTaskType(id: "2", name: "Summarize", description: ""),
  124. NKTextProcessingTaskType(id: "3", name: "Generate headline", description: ""),
  125. NKTextProcessingTaskType(id: "4", name: "Reformulate", description: "")
  126. ]
  127. self.tasks = tasks
  128. self.filteredTasks = tasks
  129. self.selectedType = types[0]
  130. self.selectedTask = filteredTasks[0]
  131. }
  132. }
  133. extension NKTextProcessingTask {
  134. struct StatusInfo {
  135. let stringKey, imageSystemName: String
  136. }
  137. var statusInfo: StatusInfo {
  138. return switch status {
  139. case 1: StatusInfo(stringKey: "_assistant_task_scheduled_", imageSystemName: "clock")
  140. case 2: StatusInfo(stringKey: "_assistant_task_in_progress_", imageSystemName: "clock.badge")
  141. case 3: StatusInfo(stringKey: "_assistant_task_completed_", imageSystemName: "checkmark.circle")
  142. case 4: StatusInfo(stringKey: "_assistant_task_failed_", imageSystemName: "exclamationmark.circle")
  143. default: StatusInfo(stringKey: "_assistant_task_unknown_", imageSystemName: "questionmark.circle")
  144. }
  145. }
  146. }