From 7daff93197a82f11a3fa881436686da5108db77a Mon Sep 17 00:00:00 2001 From: Simon Weniger Date: Tue, 19 Sep 2023 13:45:42 +0200 Subject: [PATCH 1/3] add models and source from old sdk --- Package.swift | 3 + Sources/Models/Agent.swift | 38 ++ Sources/Models/AgentDocument.swift | 22 + Sources/Models/AgentTool.swift | 23 + .../Models/AnyOfValidationErrorLocItems.swift | 16 + Sources/Models/ApiToken.swift | 23 + Sources/Models/Document.swift | 66 ++ Sources/Models/HTTPValidationError.swift | 20 + Sources/Models/PredictAgent.swift | 28 + Sources/Models/Prompt.swift | 28 + Sources/Models/SignIn.swift | 22 + Sources/Models/SignUp.swift | 26 + Sources/Models/String+Error.swift | 12 + Sources/Models/Tag.swift | 30 + Sources/Models/Tool.swift | 35 + Sources/Models/ValidationError.swift | 24 + Sources/main.swift | 632 +++++++++++++++++- 17 files changed, 1045 insertions(+), 3 deletions(-) create mode 100644 Sources/Models/Agent.swift create mode 100644 Sources/Models/AgentDocument.swift create mode 100644 Sources/Models/AgentTool.swift create mode 100644 Sources/Models/AnyOfValidationErrorLocItems.swift create mode 100644 Sources/Models/ApiToken.swift create mode 100644 Sources/Models/Document.swift create mode 100644 Sources/Models/HTTPValidationError.swift create mode 100644 Sources/Models/PredictAgent.swift create mode 100644 Sources/Models/Prompt.swift create mode 100644 Sources/Models/SignIn.swift create mode 100644 Sources/Models/SignUp.swift create mode 100644 Sources/Models/String+Error.swift create mode 100644 Sources/Models/Tag.swift create mode 100644 Sources/Models/Tool.swift create mode 100644 Sources/Models/ValidationError.swift diff --git a/Package.swift b/Package.swift index 0e9a7f4..8419efd 100644 --- a/Package.swift +++ b/Package.swift @@ -5,6 +5,9 @@ import PackageDescription let package = Package( name: "superagent-swift", + platforms: [ + .macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), + ], targets: [ // Targets are the basic building blocks of a package, defining a module or a test suite. // Targets can depend on other targets in this package and products from dependencies. diff --git a/Sources/Models/Agent.swift b/Sources/Models/Agent.swift new file mode 100644 index 0000000..951562a --- /dev/null +++ b/Sources/Models/Agent.swift @@ -0,0 +1,38 @@ +// +// Agent.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct Agent: Codable { + + public var name: String + public var type: String + public var llm: LLM? + public var hasMemory: Bool? + public var promptId: String? + + public init(name: String, type: String, llm: LLM? = nil, hasMemory: Bool? = nil, promptId: String? = nil) { + self.name = name + self.type = type + self.llm = llm + self.hasMemory = hasMemory + self.promptId = promptId + } + + public struct LLM: Codable { + public var provider: String + public var model: String + public var apiKey: String + + public init(provider: String, model: String, apiKey: String) { + self.provider = provider + self.model = model + self.apiKey = apiKey + } + } +} diff --git a/Sources/Models/AgentDocument.swift b/Sources/Models/AgentDocument.swift new file mode 100644 index 0000000..73f6626 --- /dev/null +++ b/Sources/Models/AgentDocument.swift @@ -0,0 +1,22 @@ +// +// AgentDocument.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct AgentDocument: Codable { + + public var agentId: String + public var documentId: String + + public init(agentId: String, documentId: String) { + self.agentId = agentId + self.documentId = documentId + } + + +} diff --git a/Sources/Models/AgentTool.swift b/Sources/Models/AgentTool.swift new file mode 100644 index 0000000..3ccb7db --- /dev/null +++ b/Sources/Models/AgentTool.swift @@ -0,0 +1,23 @@ +// +// AgentTool.swift +// +// Created by Simon Weniger on 09.07.23. + +// + +import Foundation + + + +public struct AgentTool: Codable { + + public var agentId: String + public var toolId: String + + public init(agentId: String, toolId: String) { + self.agentId = agentId + self.toolId = toolId + } + + +} diff --git a/Sources/Models/AnyOfValidationErrorLocItems.swift b/Sources/Models/AnyOfValidationErrorLocItems.swift new file mode 100644 index 0000000..5d53c94 --- /dev/null +++ b/Sources/Models/AnyOfValidationErrorLocItems.swift @@ -0,0 +1,16 @@ +// +// AnyOfValidationErrorLocItems.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct AnyOfValidationErrorLocItems: Codable { + + + + +} diff --git a/Sources/Models/ApiToken.swift b/Sources/Models/ApiToken.swift new file mode 100644 index 0000000..a224a0e --- /dev/null +++ b/Sources/Models/ApiToken.swift @@ -0,0 +1,23 @@ +// +// ApiToken.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct ApiToken: Codable { + + public var _description: String + + public init(_description: String) { + self._description = _description + } + + public enum CodingKeys: String, CodingKey { + case _description = "description" + } + +} diff --git a/Sources/Models/Document.swift b/Sources/Models/Document.swift new file mode 100644 index 0000000..0710b4b --- /dev/null +++ b/Sources/Models/Document.swift @@ -0,0 +1,66 @@ +// +// Document.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct Document { + + public var type: String + public var url: String? + public var description: String? + public var content: String + public var name: String + public var authorization: Any? + public var metadata: Any? + public var fromPage: Int? + public var toPage: Int? + public var splitter: Splitter? + + public init(type: String, url: String? = nil, name: String, description: String, content: String, authorization: Any? = nil, metadata: Any? = nil, fromPage: Int? = nil, toPage: Int? = nil, splitter: Splitter? = nil) { + self.type = type + self.url = url + self.description = description + self.content = content + self.name = name + self.authorization = authorization + self.metadata = metadata + self.fromPage = fromPage + self.toPage = toPage + self.splitter = splitter + } + + public enum CodingKeys: String, CodingKey { + case type + case url + case name + case description + case content + case authorization + case metadata + case fromPage = "from_page" + case toPage = "to_page" + case splitter + } + + public struct Splitter: Codable { + public var type: String + public var chunkSize: Int + public var chunkOverlap: Int + + public init(type: String, chunkSize: Int, chunkOverlap: Int) { + self.type = type + self.chunkSize = chunkSize + self.chunkOverlap = chunkOverlap + } + public enum CodingKeys: String, CodingKey { + case type + case chunkSize = "chunk_size" + case chunkOverlap = "chunk_overlap" + } + } +} diff --git a/Sources/Models/HTTPValidationError.swift b/Sources/Models/HTTPValidationError.swift new file mode 100644 index 0000000..01ed838 --- /dev/null +++ b/Sources/Models/HTTPValidationError.swift @@ -0,0 +1,20 @@ +// +// HTTPValidationError.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct HTTPValidationError: Codable { + + public var detail: [ValidationError]? + + public init(detail: [ValidationError]? = nil) { + self.detail = detail + } + + +} diff --git a/Sources/Models/PredictAgent.swift b/Sources/Models/PredictAgent.swift new file mode 100644 index 0000000..15a235d --- /dev/null +++ b/Sources/Models/PredictAgent.swift @@ -0,0 +1,28 @@ +// +// PredictAgent.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + +public struct PredictAgent { + + public var input: [String:String] + public var hasStreaming: Bool? + public var session: String? + + public init(input: [String:String], hasStreaming: Bool? = nil, session: String) { + self.input = input + self.hasStreaming = hasStreaming + self.session = session + } + + public enum CodingKeys: String, CodingKey { + case input + case hasStreaming = "has_streaming" + case session + } + +} diff --git a/Sources/Models/Prompt.swift b/Sources/Models/Prompt.swift new file mode 100644 index 0000000..3818490 --- /dev/null +++ b/Sources/Models/Prompt.swift @@ -0,0 +1,28 @@ +// +// Prompt.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + +public struct Prompt: Decodable { + + public var name: String + public var inputVariables: [String] + public var template: String + + public enum CodingKeys: String, CodingKey { + case name = "name" + case inputVariables = "input_variables" + case template = "template" + } + + public init(name: String, inputVariables: [String], template: String) { + self.name = name + self.inputVariables = inputVariables + self.template = template + } + +} diff --git a/Sources/Models/SignIn.swift b/Sources/Models/SignIn.swift new file mode 100644 index 0000000..3015f84 --- /dev/null +++ b/Sources/Models/SignIn.swift @@ -0,0 +1,22 @@ +// +// SignIn.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct SignIn: Codable { + + public var email: String + public var password: String + + public init(email: String, password: String) { + self.email = email + self.password = password + } + + +} diff --git a/Sources/Models/SignUp.swift b/Sources/Models/SignUp.swift new file mode 100644 index 0000000..7f2b078 --- /dev/null +++ b/Sources/Models/SignUp.swift @@ -0,0 +1,26 @@ +// +// SignUp.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct SignUp { + + public var email: String + public var password: String + public var name: String? + public var metadata: Any? + + public init(email: String, password: String, name: String? = nil, metadata: Any? = nil) { + self.email = email + self.password = password + self.name = name + self.metadata = metadata + } + + +} diff --git a/Sources/Models/String+Error.swift b/Sources/Models/String+Error.swift new file mode 100644 index 0000000..4b53b25 --- /dev/null +++ b/Sources/Models/String+Error.swift @@ -0,0 +1,12 @@ +// +// String+Error.swift +// +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + +extension String: LocalizedError { + public var errorDescription: String? { return self } +} diff --git a/Sources/Models/Tag.swift b/Sources/Models/Tag.swift new file mode 100644 index 0000000..4ee47f6 --- /dev/null +++ b/Sources/Models/Tag.swift @@ -0,0 +1,30 @@ +// +// File.swift +// +// +// Created by vonweniger on 21.07.23. +// + +import Foundation + + + +public struct Tag { + + public var name: String + public var color: String + public var userId: String? + + public init(name: String, color: String, userId: String?) { + self.name = name + self.color = color + self.userId = color + } + + public enum CodingKeys: String, CodingKey { + case name + case color + case userId + } + +} diff --git a/Sources/Models/Tool.swift b/Sources/Models/Tool.swift new file mode 100644 index 0000000..b490cc0 --- /dev/null +++ b/Sources/Models/Tool.swift @@ -0,0 +1,35 @@ +// +// Tool.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct Tool { + + public var name: String + public var type: String + public var _description: String + public var authorization: Any? + public var metadata: Any? + + public init(name: String, type: String, _description: String, authorization: Any? = nil, metadata: Any? = nil) { + self.name = name + self.type = type + self._description = _description + self.authorization = authorization + self.metadata = metadata + } + + public enum CodingKeys: String, CodingKey { + case name + case type + case _description = "description" + case authorization + case metadata + } + +} diff --git a/Sources/Models/ValidationError.swift b/Sources/Models/ValidationError.swift new file mode 100644 index 0000000..9c91f5d --- /dev/null +++ b/Sources/Models/ValidationError.swift @@ -0,0 +1,24 @@ +// +// ValidationError.swift +// +// Created by Simon Weniger on 09.07.23. +// + +import Foundation + + + +public struct ValidationError: Codable { + + public var loc: [AnyOfValidationErrorLocItems] + public var msg: String + public var type: String + + public init(loc: [AnyOfValidationErrorLocItems], msg: String, type: String) { + self.loc = loc + self.msg = msg + self.type = type + } + + +} diff --git a/Sources/main.swift b/Sources/main.swift index 44e20d5..fe36f99 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -1,4 +1,630 @@ -// The Swift Programming Language -// https://docs.swift.org/swift-book +// +// main.swift +// +// +// Created by Simon Weniger (Aiden Technologies UG) on 19.09.23 +// + + +import Foundation + +enum HttpMethod: String { + case get = "GET" + case post = "POST" + case delete = "DELETE" + case patch = "PATCH" +} + +enum SuperagentError: Error { + case invalidResponse + case requestFailed + case failedToRetrieve + case failedToUpdate + case failedToCreate +} + +@available(macOS 12.0, *) +public struct SuperagentSDK { + + public var baseUrl: String + public var apiKey: String + + // init auth and api url + public init(apiKey: String, apiUrl: String?) { + self.baseUrl = apiUrl ?? "https://api.superagent.sh/api/v1" + self.apiKey = apiKey + } + + //createRequest + private func createRequest(method: HttpMethod, endpoint: String, data: [String: Any]? = nil) throws -> URLRequest { + guard let url = URL(string: "\(self.baseUrl)\(endpoint)") else { + throw URLError(.badURL) + } + + var request = URLRequest(url: url) + request.httpMethod = method.rawValue.uppercased() + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + request.addValue("Bearer \(self.apiKey)", forHTTPHeaderField: "Authorization") + + if let data = data { + if method == .get { + var components = URLComponents(url: url, resolvingAgainstBaseURL: false)! + components.queryItems = data.map { + URLQueryItem(name: $0.key, value: "\($0.value)") + } + guard let componentUrl = components.url else { throw SuperagentError.invalidResponse } + request.url = componentUrl + } else { + let jsonData = try JSONSerialization.data(withJSONObject: data) + request.httpBody = jsonData + + if data.keys.contains("input") { + request.setValue(self.apiKey, forHTTPHeaderField: "X-SUPERAGENT-API-KEY") + } + } + } + return request + } + + // defined Request + private func request(method: HttpMethod, endpoint: String, data: [String: Any]? = nil) async throws -> Any { + let request = try createRequest(method: method, endpoint: endpoint, data: data) + let (data, response) = try await URLSession.shared.data(for: request) + + if let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode { + if let output = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { + return output + } else { + throw SuperagentError.invalidResponse + } + } + return response + } + + //Prompts + ///Retuns a specific prompt + public func getPrompt(id: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/prompts/\(id)") + guard let responseData = data as? [String: Any], + let promptData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("getPrompt result: \(promptData)") + + //let decoder = JSONDecoder() + //let jsonDataEncoded = try JSONSerialization.data(withJSONObject: jsonData, options: []) + //let prompt = try decoder.decode(Prompt.self, from: jsonDataEncoded) + + return promptData + } + + ///Delete prompt + public func deletePrompt(id: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/prompts/\(id)") + guard let responseData = data as? [String: Any], + let success = responseData["success"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("deletePrompt result: \(success)") + + return success + } + + ///Lists all prompts + public func listPrompts() async throws -> [[String: Any]] { + let data = try await request(method: .get, endpoint: "/prompts") + + guard let responseData = data as? [String: Any], + let promptsData = responseData["data"] as? [[String: Any]] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("listPrompts result: \(promptsData)") + + //let decoder = JSONDecoder() + //var prompts = [Prompt]() + + //for json in jsonArray { + // let jsonData = try JSONSerialization.data(withJSONObject: json, options: []) + // let prompt = try decoder.decode(Prompt.self, from: jsonData) + // prompts.append(prompt) + //} + + return promptsData + } + + ///Patch a specific prompt + public func updatePrompt(promptId: String, newPrompt: Prompt) async throws -> [String: Any] { + let payload: [String: Any] = ["name": newPrompt.name, "input_variables": newPrompt.inputVariables, "template": newPrompt.template] + let data = try await request(method: .patch, endpoint: "/prompts/\(promptId)", data: payload) + + guard let responseData = data as? [String: Any], + let promptData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("updatePrompt result: \(promptData)") + + return promptData + } + + ///Create a new prompt + public func createPrompt(prompt: Prompt) async throws -> [String: Any] { + let payload: [String: Any] = ["name": prompt.name, "input_variables": prompt.inputVariables, "template": prompt.template] + let data = try await request(method: .post, endpoint: "/prompts", data: payload) + + guard let responseData = data as? [String: Any], + let promptData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("createPrompt result: \(promptData)") + + return promptData + } + + //Documents + ///Returns a specific document + public func getDocument(id: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/documents/\(id)") + + guard let responseData = data as? [String: Any], + let documentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("getDocument result: \(documentData)") + + return documentData + } + + ///Delete document + public func deleteDocument(id: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/documents/\(id)") + + guard let responseData = data as? [String: Any], + let documentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("deleteDocument result: \(documentData)") + + return documentData + } + + ///Lists all documents + public func listDocuments() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/documents") + + guard let responseData = data as? [String: Any], + let documentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + Swift.print("listDocuments result: \(documentData)") + + return documentData + } + + ///Create a new document + public func createDocument(document: Document) async throws -> [String: Any] { + let payload: [String: Any] = ["name": document.name, + "description" : document.description as Any, + "content" : document.content, + "splitter": ["type": document.splitter?.type as Any, "chunk_size": document.splitter?.chunkSize as Any, "chunk_overlap": document.splitter?.chunkOverlap as Any], + "url": document.url as Any, + "type": document.type, + "authorization": document.authorization as Any] + let data = try await request(method: .post, endpoint: "/documents", data: payload) + + guard let responseData = data as? [String: Any], + let documentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("createDocument result: \(documentData)") +#endif + + return documentData + } + + ///Patch a document + public func updateDocument(id: String, document: Document) async throws -> [String: Any] { + let payload: [String: Any] = ["name": document.name, + "description" : document.description as Any, + "content" : document.content, + "splitter": ["type": document.splitter?.type as Any, "chunk_size": document.splitter?.chunkSize as Any, "chunk_overlap": document.splitter?.chunkOverlap as Any], + "url": document.url as Any, + "type": document.type, + "authorization": document.authorization as Any] + let data = try await request(method: .patch, endpoint: "/documents/\(id)", data: payload) + + guard let responseData = data as? [String: Any], + let documentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + + } + +#if DEBUG + Swift.print("updateDocument result: \(documentData)") +#endif + + return documentData + } + + //Agents + ///Returns a specific agent + public func getAgent(id: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agents/\(id)") + + guard let responseData = data as? [String: Any], + let agentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("getAgent result: \(agentData)") +#endif + + //let decoder = JSONDecoder() + //let jsonDataEncoded = try JSONSerialization.data(withJSONObject: jsonData, options: []) + //let agent = try decoder.decode(Agent.self, from: jsonDataEncoded) + + return agentData + } + + ///Delete agent + public func deleteAgent(id: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/agents/\(id)") + + guard let responseData = data as? [String: Any], + let agentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("deleteAgent result: \(agentData)") +#endif + + return agentData + } + + ///Lists all agents + public func listAgents() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agents") + + guard let responseData = data as? [String: Any], + let agentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("listAgents result: \(agentData)") +#endif + + return agentData + } + + ///Create a new agent + public func createAgent(agent: Agent) async throws -> [String: Any] { + let payload: [String: Any] = ["name": agent.name, + "llm": ["provider": agent.llm?.provider, "model": agent.llm?.model, "api_key": agent.llm?.apiKey], + "type": agent.type, + "hasMemory": agent.hasMemory as Any, + "promptId": agent.promptId ?? ""] + let data = try await request(method: .post, endpoint: "/agents", data: payload) + + guard let responseData = data as? [String: Any], + let agentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("createAgent result: \(agentData)") +#endif + // WE MAY ADD RESPONSE MODELS LATER AND ADD JSON DECODING + + //print("response data:\(jsonData)") + + //let decoder = JSONDecoder() + //let jsonDataEncoded = try JSONSerialization.data(withJSONObject: jsonData, options: []) + + //print("JsonDataEncoded \(jsonDataEncoded)") + //let agent = try decoder.decode(Agent.self, from: jsonDataEncoded) + + //print("returned Agent: \(agent)") + + return agentData + } + + + ///Create a new prediction + public func createPrediction(agentId: String, prediction: PredictAgent) async throws -> String { + //print("create Prediction called") + let payload: [String: Any] = ["input": prediction.input, + "has_Streaming": prediction.hasStreaming as Any, + "session": prediction.session as Any] + +#if DEBUG + Swift.print("Prediction payload: \(payload)") +#endif + let data = try await request(method: .post, endpoint: "/agents/\(agentId)/predict", data: payload) +#if DEBUG + Swift.print("Prediction data:\(data)") +#endif + guard let responseData = data as? [String: Any], + let predictionData = responseData["data"] as? String else { + throw SuperagentError.failedToRetrieve + } + Swift.print("createPrediction result: \(predictionData)") + return predictionData + } + + //Agent Library + ///Get all Agents from the Library + public func listLibraryAgents() async throws -> [[String: Any]] { + let data = try await request(method: .get, endpoint: "/agents/library") + + guard let responseData = data as? [String: Any], + let agentLibrary = responseData["data"] as? [[String: Any]] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getAgentDocuments result: \(agentLibrary)") +#endif + return agentLibrary + } + + + //Agent Documents + ///Get all Documents from an Agent + public func listAgentDocuments() async throws -> [[String: Any]] { + let data = try await request(method: .get, endpoint: "/agent-documents") + + guard let responseData = data as? [String: Any], + let agentDocuments = responseData["data"] as? [[String: Any]] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getAgentDocuments result: \(agentDocuments)") +#endif + return agentDocuments + } + + ///Get all Documents from an Agent + public func getAgentDocument(agentDocumentId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agent-documents\(agentDocumentId)") + + guard let responseData = data as? [String: Any], + let agentDocument = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getAgentDocuments result: \(agentDocument)") +#endif + return agentDocument + } + + ///Add a Document to an Agent + public func addDocumentToAgent(documentId: String, agentId: String) async throws -> [String: Any] { + let payload: [String: Any] = ["documentId": documentId, "agentId": agentId] + let data = try await request(method: .post, endpoint: "/agents", data: payload) + + guard let responseData = data as? [String: Any], + let agentDocument = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToCreate + } +#if DEBUG + Swift.print("createAgentDocument result: \(agentDocument)") +#endif + return agentDocument + } + + ///Delete a Document from an Agent + public func deleteAgentDocument(agentDocumentId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/agent-documents/\(agentDocumentId)") + + guard let responseData = data as? [String: Any], + let agentDocument = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("deleteAgentDocument result: \(agentDocument)") +#endif + return agentDocument + } + + //Agent Tools + ///Get all Tools from an Agent + public func listAgentTools(agentToolId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agent-tools/\(agentToolId)") + + guard let responseData = data as? [String: Any], + let agentTool = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getAgentTools result: \(agentTool)") +#endif + return agentTool + } + + ///Get all Tools from an Agent + public func getAgentTool() async throws -> [[String: Any]] { + let data = try await request(method: .get, endpoint: "/agent-tools") + + guard let responseData = data as? [String: Any], + let agentTools = responseData["data"] as? [[String: Any]] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getAgentTools result: \(agentTools)") +#endif + return agentTools + } + + ///Add a Tool to an Agent + public func addToolToAgent(agentId: String, toolId: String) async throws -> [String: Any] { + let payload: [String: Any] = ["agentId": agentId, "toolId": toolId] + let data = try await request(method: .post, endpoint: "/agent-tools", data: payload) + + guard let responseData = data as? [String: Any], + let agentToolData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToUpdate + } +#if DEBUG + Swift.print("addToolToAgent result: \(agentToolData)") +#endif + return agentToolData + } + + ///Delete a Tool from an Agent + public func deleteAgentTool(agentToolId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/agent-documents/\(agentToolId)") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.requestFailed + } +#if DEBUG + Swift.print("deleteAgentTool result: \(success)") +#endif + return success + } + + //Tools + ///Returns a specific tool + public func getTool(id: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/tools/\(id)") + + guard let responseData = data as? [String: Any], + let toolData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getTool result: \(toolData)") +#endif + return toolData + } + + ///Delete tool + public func deleteTool(id: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/tools/\(id)") + + guard let responseData = data as? [String: Any], + let toolData = responseData["data"] as? [String: Any] else { + throw SuperagentError.requestFailed + } +#if DEBUG + Swift.print("deleteTool result: \(toolData)") +#endif + return toolData + } + + ///Lists all tools + public func listTools() async throws -> [[String: Any]] { + let data = try await request(method: .get, endpoint: "/tools") + + guard let responseData = data as? [String: Any], + let toolData = responseData["data"] as? [[String: Any]] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("listTools result: \(toolData)") +#endif + return toolData + } + + ///Create a new tool + public func createTool(tool: Tool) async throws -> [String: Any] { + var payload: [String: Any] = ["name": tool.name, "type": tool.type] + if let metadata = tool.metadata { + payload["metadata"] = metadata + } + let data = try await request(method: .post, endpoint: "/tools", data: payload) + + guard let responseData = data as? [String: Any], + let toolData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToCreate + } +#if DEBUG + Swift.print("createTool result: \(toolData)") +#endif + return toolData + } + + //Tags + ///Returns a specific tag + public func getTag(id: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/tags/\(id)") + + guard let responseData = data as? [String: Any], + let tagData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("getTag result: \(tagData)") +#endif + return tagData + } + + ///Delete tool + public func deleteTag(id: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/tags/\(id)") + + guard let responseData = data as? [String: Any], + let tagData = responseData["data"] as? [String: Any] else { + throw SuperagentError.requestFailed + } +#if DEBUG + Swift.print("deleteTag result: \(tagData)") +#endif + return tagData + } + + ///Lists all tools + public func listTags() async throws -> [[String: Any]] { + let data = try await request(method: .get, endpoint: "/tags") + + guard let responseData = data as? [String: Any], + let tagsData = responseData["data"] as? [[String: Any]] else { + throw SuperagentError.failedToRetrieve + } +#if DEBUG + Swift.print("listTagss result: \(tagsData)") +#endif + return tagsData + } + ///Create a new tool + public func createTag(tag: Tag) async throws -> [String: Any] { + var payload: [String: Any] = ["name": tag.name, "type": tag.color, "userId": tag.userId ?? ""] + let data = try await request(method: .post, endpoint: "/tags", data: payload) + + guard let responseData = data as? [String: Any], + let tagData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToCreate + } +#if DEBUG + Swift.print("createTag result: \(tagData)") +#endif + return tagData + } + + ///Patch a tag + public func updateTag(id: String, newTag: Tag) async throws -> [String: Any] { + var payload: [String: Any] = ["name": newTag.name, "type": newTag.color] + let data = try await request(method: .post, endpoint: "/tags/\(id)", data: payload) + + guard let responseData = data as? [String: Any], + let tagData = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToUpdate + } +#if DEBUG + Swift.print("updateTag result: \(tagData)") +#endif + return tagData + } +} -print("Hello, world!") From 4132d07bcbb84114ade3182350a151882cc76b03 Mon Sep 17 00:00:00 2001 From: Simon Weniger Date: Tue, 19 Sep 2023 16:17:00 +0200 Subject: [PATCH 2/3] add new agent function --- Sources/Models/Agent.swift | 38 +-- Sources/Models/AgentDocument.swift | 22 -- Sources/Models/AgentTool.swift | 23 -- Sources/Models/PredictAgent.swift | 28 -- Sources/Models/Request.swift | 21 ++ Sources/main.swift | 520 ++++++++--------------------- 6 files changed, 165 insertions(+), 487 deletions(-) delete mode 100644 Sources/Models/AgentDocument.swift delete mode 100644 Sources/Models/AgentTool.swift delete mode 100644 Sources/Models/PredictAgent.swift create mode 100644 Sources/Models/Request.swift diff --git a/Sources/Models/Agent.swift b/Sources/Models/Agent.swift index 951562a..febcc1e 100644 --- a/Sources/Models/Agent.swift +++ b/Sources/Models/Agent.swift @@ -10,29 +10,19 @@ import Foundation public struct Agent: Codable { - public var name: String - public var type: String - public var llm: LLM? - public var hasMemory: Bool? - public var promptId: String? - - public init(name: String, type: String, llm: LLM? = nil, hasMemory: Bool? = nil, promptId: String? = nil) { - self.name = name - self.type = type - self.llm = llm - self.hasMemory = hasMemory - self.promptId = promptId + public var isActive: Bool + public var name: String + public var prompt: String? + public var llmModel: String + public var description: String + public var avatar: String? + + public init(name: String, isActive: Bool, prompt: String? = nil, llmModel: String, description: String, avatar: String? = nil) { + self.isActive = isActive + self.name = name + self.prompt = prompt + self.llmModel = llmModel + self.description = description + self.avatar = avatar } - - public struct LLM: Codable { - public var provider: String - public var model: String - public var apiKey: String - - public init(provider: String, model: String, apiKey: String) { - self.provider = provider - self.model = model - self.apiKey = apiKey - } - } } diff --git a/Sources/Models/AgentDocument.swift b/Sources/Models/AgentDocument.swift deleted file mode 100644 index 73f6626..0000000 --- a/Sources/Models/AgentDocument.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// AgentDocument.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct AgentDocument: Codable { - - public var agentId: String - public var documentId: String - - public init(agentId: String, documentId: String) { - self.agentId = agentId - self.documentId = documentId - } - - -} diff --git a/Sources/Models/AgentTool.swift b/Sources/Models/AgentTool.swift deleted file mode 100644 index 3ccb7db..0000000 --- a/Sources/Models/AgentTool.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// AgentTool.swift -// -// Created by Simon Weniger on 09.07.23. - -// - -import Foundation - - - -public struct AgentTool: Codable { - - public var agentId: String - public var toolId: String - - public init(agentId: String, toolId: String) { - self.agentId = agentId - self.toolId = toolId - } - - -} diff --git a/Sources/Models/PredictAgent.swift b/Sources/Models/PredictAgent.swift deleted file mode 100644 index 15a235d..0000000 --- a/Sources/Models/PredictAgent.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// PredictAgent.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - -public struct PredictAgent { - - public var input: [String:String] - public var hasStreaming: Bool? - public var session: String? - - public init(input: [String:String], hasStreaming: Bool? = nil, session: String) { - self.input = input - self.hasStreaming = hasStreaming - self.session = session - } - - public enum CodingKeys: String, CodingKey { - case input - case hasStreaming = "has_streaming" - case session - } - -} diff --git a/Sources/Models/Request.swift b/Sources/Models/Request.swift new file mode 100644 index 0000000..739f5d0 --- /dev/null +++ b/Sources/Models/Request.swift @@ -0,0 +1,21 @@ +// +// PredictAgent.swift +// +// Created by Simon Weniger (Aiden Technologies) on 09.07.23. +// + +import Foundation + +public struct Request { + + public var input: String + public var sessionId: String? + public var enableStreaming: Bool + + public init(input: String, sessionId: String? = "", enableStreaming: Bool) { + self.input = input + self.sessionId = sessionId + self.enableStreaming = enableStreaming + } + +} diff --git a/Sources/main.swift b/Sources/main.swift index fe36f99..4cb5873 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -81,182 +81,53 @@ public struct SuperagentSDK { return response } - //Prompts - ///Retuns a specific prompt - public func getPrompt(id: String) async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/prompts/\(id)") - guard let responseData = data as? [String: Any], - let promptData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("getPrompt result: \(promptData)") - - //let decoder = JSONDecoder() - //let jsonDataEncoded = try JSONSerialization.data(withJSONObject: jsonData, options: []) - //let prompt = try decoder.decode(Prompt.self, from: jsonDataEncoded) - - return promptData - } + //MARK: - START VERSION 1.0 - ///Delete prompt - public func deletePrompt(id: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/prompts/\(id)") - guard let responseData = data as? [String: Any], - let success = responseData["success"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("deletePrompt result: \(success)") - - return success - } - ///Lists all prompts - public func listPrompts() async throws -> [[String: Any]] { - let data = try await request(method: .get, endpoint: "/prompts") - - guard let responseData = data as? [String: Any], - let promptsData = responseData["data"] as? [[String: Any]] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("listPrompts result: \(promptsData)") - - //let decoder = JSONDecoder() - //var prompts = [Prompt]() - - //for json in jsonArray { - // let jsonData = try JSONSerialization.data(withJSONObject: json, options: []) - // let prompt = try decoder.decode(Prompt.self, from: jsonData) - // prompts.append(prompt) - //} - - return promptsData - } - ///Patch a specific prompt - public func updatePrompt(promptId: String, newPrompt: Prompt) async throws -> [String: Any] { - let payload: [String: Any] = ["name": newPrompt.name, "input_variables": newPrompt.inputVariables, "template": newPrompt.template] - let data = try await request(method: .patch, endpoint: "/prompts/\(promptId)", data: payload) - - guard let responseData = data as? [String: Any], - let promptData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("updatePrompt result: \(promptData)") - - return promptData - } - - ///Create a new prompt - public func createPrompt(prompt: Prompt) async throws -> [String: Any] { - let payload: [String: Any] = ["name": prompt.name, "input_variables": prompt.inputVariables, "template": prompt.template] - let data = try await request(method: .post, endpoint: "/prompts", data: payload) - - guard let responseData = data as? [String: Any], - let promptData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("createPrompt result: \(promptData)") - - return promptData - } - - //Documents - ///Returns a specific document - public func getDocument(id: String) async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/documents/\(id)") - - guard let responseData = data as? [String: Any], - let documentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("getDocument result: \(documentData)") - - return documentData - } + //MARK: - Agent - ///Delete document - public func deleteDocument(id: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/documents/\(id)") - - guard let responseData = data as? [String: Any], - let documentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("deleteDocument result: \(documentData)") - - return documentData - } - - ///Lists all documents - public func listDocuments() async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/documents") - - guard let responseData = data as? [String: Any], - let documentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } - - Swift.print("listDocuments result: \(documentData)") - - return documentData - } - - ///Create a new document - public func createDocument(document: Document) async throws -> [String: Any] { - let payload: [String: Any] = ["name": document.name, - "description" : document.description as Any, - "content" : document.content, - "splitter": ["type": document.splitter?.type as Any, "chunk_size": document.splitter?.chunkSize as Any, "chunk_overlap": document.splitter?.chunkOverlap as Any], - "url": document.url as Any, - "type": document.type, - "authorization": document.authorization as Any] - let data = try await request(method: .post, endpoint: "/documents", data: payload) + //List + ///List all agents + public func listAgents() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agents") guard let responseData = data as? [String: Any], - let documentData = responseData["data"] as? [String: Any] else { + let agentData = responseData["data"] as? [String: Any] else { throw SuperagentError.failedToRetrieve } #if DEBUG - Swift.print("createDocument result: \(documentData)") + Swift.print("listAgents result: \(agentData)") #endif - return documentData + return agentData } - ///Patch a document - public func updateDocument(id: String, document: Document) async throws -> [String: Any] { - let payload: [String: Any] = ["name": document.name, - "description" : document.description as Any, - "content" : document.content, - "splitter": ["type": document.splitter?.type as Any, "chunk_size": document.splitter?.chunkSize as Any, "chunk_overlap": document.splitter?.chunkOverlap as Any], - "url": document.url as Any, - "type": document.type, - "authorization": document.authorization as Any] - let data = try await request(method: .patch, endpoint: "/documents/\(id)", data: payload) + //Create + ///Create a new agent + public func createAgent(agent: Agent) async throws -> [String: Any] { + let payload: [String: Any] = ["isActive": agent.isActive, + "name": agent.name, + "prompt": agent.prompt ?? "", + "llmModel": agent.llmModel, + "description": agent.description, + "avatar": agent.avatar ?? ""] + let data = try await request(method: .post, endpoint: "/agents", data: payload) guard let responseData = data as? [String: Any], - let documentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - + let agentData = responseData["data"] as? [String: Any] else { + throw SuperagentError.requestFailed } - #if DEBUG - Swift.print("updateDocument result: \(documentData)") + Swift.print("createAgent result: \(agentData)") #endif - return documentData + return agentData } - //Agents - ///Returns a specific agent + //Get + ///Get a single agent public func getAgent(id: String) async throws -> [String: Any] { let data = try await request(method: .get, endpoint: "/agents/\(id)") @@ -269,362 +140,231 @@ public struct SuperagentSDK { Swift.print("getAgent result: \(agentData)") #endif - //let decoder = JSONDecoder() - //let jsonDataEncoded = try JSONSerialization.data(withJSONObject: jsonData, options: []) - //let agent = try decoder.decode(Agent.self, from: jsonDataEncoded) - return agentData } - ///Delete agent - public func deleteAgent(id: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/agents/\(id)") + //Update + ///Patch an agent + public func updateAgent(agentId: String, newAgent: Agent) async throws -> [String: Any] { + let payload: [String: Any] = ["isActive": newAgent.isActive, + "name": newAgent.name, + "prompt": newAgent.prompt ?? "", + "llmModel": newAgent.llmModel, + "description": newAgent.description, + "avatar": newAgent.avatar ?? ""] + let data = try await request(method: .post, endpoint: "/agents/\(agentId)", data: payload) guard let responseData = data as? [String: Any], let agentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve + throw SuperagentError.failedToUpdate } - #if DEBUG - Swift.print("deleteAgent result: \(agentData)") + Swift.print("createAgent result: \(agentData)") #endif return agentData } - ///Lists all agents - public func listAgents() async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/agents") + ///Delete agent + public func deleteAgent(id: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/agents/\(id)") guard let responseData = data as? [String: Any], let agentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve + throw SuperagentError.requestFailed } #if DEBUG - Swift.print("listAgents result: \(agentData)") + Swift.print("deleteAgent result: \(agentData)") #endif return agentData } - ///Create a new agent - public func createAgent(agent: Agent) async throws -> [String: Any] { - let payload: [String: Any] = ["name": agent.name, - "llm": ["provider": agent.llm?.provider, "model": agent.llm?.model, "api_key": agent.llm?.apiKey], - "type": agent.type, - "hasMemory": agent.hasMemory as Any, - "promptId": agent.promptId ?? ""] - let data = try await request(method: .post, endpoint: "/agents", data: payload) + //Invoke + ///Invoke an agent + public func invokeAgent(agentId: String, agentRequest: Request) async throws -> String { + let payload: [String: Any] = ["input": agentRequest.input, + "sessionId": agentRequest.sessionId as Any, + "enableStreaming": agentRequest.enableStreaming as Any] - guard let responseData = data as? [String: Any], - let agentData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } -#if DEBUG - Swift.print("createAgent result: \(agentData)") -#endif - // WE MAY ADD RESPONSE MODELS LATER AND ADD JSON DECODING + let data = try await request(method: .post, endpoint: "/agents/\(agentId)/invoke", data: payload) - //print("response data:\(jsonData)") - - //let decoder = JSONDecoder() - //let jsonDataEncoded = try JSONSerialization.data(withJSONObject: jsonData, options: []) - - //print("JsonDataEncoded \(jsonDataEncoded)") - //let agent = try decoder.decode(Agent.self, from: jsonDataEncoded) - - //print("returned Agent: \(agent)") - - return agentData - } - - - ///Create a new prediction - public func createPrediction(agentId: String, prediction: PredictAgent) async throws -> String { - //print("create Prediction called") - let payload: [String: Any] = ["input": prediction.input, - "has_Streaming": prediction.hasStreaming as Any, - "session": prediction.session as Any] - -#if DEBUG - Swift.print("Prediction payload: \(payload)") -#endif - let data = try await request(method: .post, endpoint: "/agents/\(agentId)/predict", data: payload) #if DEBUG Swift.print("Prediction data:\(data)") #endif + guard let responseData = data as? [String: Any], let predictionData = responseData["data"] as? String else { throw SuperagentError.failedToRetrieve } - Swift.print("createPrediction result: \(predictionData)") - return predictionData - } - - //Agent Library - ///Get all Agents from the Library - public func listLibraryAgents() async throws -> [[String: Any]] { - let data = try await request(method: .get, endpoint: "/agents/library") - guard let responseData = data as? [String: Any], - let agentLibrary = responseData["data"] as? [[String: Any]] else { - throw SuperagentError.failedToRetrieve - } #if DEBUG - Swift.print("getAgentDocuments result: \(agentLibrary)") + Swift.print("createPrediction result: \(predictionData)") #endif - return agentLibrary - } - - - //Agent Documents - ///Get all Documents from an Agent - public func listAgentDocuments() async throws -> [[String: Any]] { - let data = try await request(method: .get, endpoint: "/agent-documents") - guard let responseData = data as? [String: Any], - let agentDocuments = responseData["data"] as? [[String: Any]] else { - throw SuperagentError.failedToRetrieve - } -#if DEBUG - Swift.print("getAgentDocuments result: \(agentDocuments)") -#endif - return agentDocuments + return predictionData } - ///Get all Documents from an Agent - public func getAgentDocument(agentDocumentId: String) async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/agent-documents\(agentDocumentId)") + //Add LLM + ///Add LLM to agent + public func addLlmToAgent(agentId: String, llmId: String) async throws -> String { + let data = try await request(method: .post, endpoint: "/agents/\(agentId)/llms", data: ["llmId": llmId]) guard let responseData = data as? [String: Any], - let agentDocument = responseData["data"] as? [String: Any] else { + let agentData = responseData["data"] as? String else { throw SuperagentError.failedToRetrieve } -#if DEBUG - Swift.print("getAgentDocuments result: \(agentDocument)") -#endif - return agentDocument - } - - ///Add a Document to an Agent - public func addDocumentToAgent(documentId: String, agentId: String) async throws -> [String: Any] { - let payload: [String: Any] = ["documentId": documentId, "agentId": agentId] - let data = try await request(method: .post, endpoint: "/agents", data: payload) - guard let responseData = data as? [String: Any], - let agentDocument = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToCreate - } #if DEBUG - Swift.print("createAgentDocument result: \(agentDocument)") + Swift.print("add LLM To Agent result: \(agentData)") #endif - return agentDocument - } - - ///Delete a Document from an Agent - public func deleteAgentDocument(agentDocumentId: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/agent-documents/\(agentDocumentId)") - guard let responseData = data as? [String: Any], - let agentDocument = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } -#if DEBUG - Swift.print("deleteAgentDocument result: \(agentDocument)") -#endif - return agentDocument + return agentData } - //Agent Tools - ///Get all Tools from an Agent - public func listAgentTools(agentToolId: String) async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/agent-tools/\(agentToolId)") + //Remove LLM + ///Remove LLM from agent + public func removeLlmfromAgent(agentId: String, llmId: String) async throws -> String { + let data = try await request(method: .delete, endpoint: "/agents/\(agentId)/llms/\(llmId)") guard let responseData = data as? [String: Any], - let agentTool = responseData["data"] as? [String: Any] else { + let agentData = responseData["data"] as? String else { throw SuperagentError.failedToRetrieve } + #if DEBUG - Swift.print("getAgentTools result: \(agentTool)") + Swift.print("remove LLM from Agent result: \(agentData)") #endif - return agentTool + + return agentData } - ///Get all Tools from an Agent - public func getAgentTool() async throws -> [[String: Any]] { - let data = try await request(method: .get, endpoint: "/agent-tools") + //List Tools + ///List agent tools + public func listAgentTools(agentId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agents/\(agentId)/tools") guard let responseData = data as? [String: Any], - let agentTools = responseData["data"] as? [[String: Any]] else { + let agentTools = responseData["data"] as? [String: Any] else { throw SuperagentError.failedToRetrieve } #if DEBUG - Swift.print("getAgentTools result: \(agentTools)") + Swift.print("list agent tools result: \(agentTools)") #endif return agentTools } - ///Add a Tool to an Agent + + //Add Tool + ///Add tool to agent public func addToolToAgent(agentId: String, toolId: String) async throws -> [String: Any] { - let payload: [String: Any] = ["agentId": agentId, "toolId": toolId] - let data = try await request(method: .post, endpoint: "/agent-tools", data: payload) + let data = try await request(method: .post, endpoint: "/agents/\(agentId)/tools", data: ["toolId": toolId]) guard let responseData = data as? [String: Any], - let agentToolData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToUpdate + let agentTools = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve } #if DEBUG - Swift.print("addToolToAgent result: \(agentToolData)") + Swift.print("add tool to agent result: \(agentTools)") #endif - return agentToolData + return agentTools } - ///Delete a Tool from an Agent - public func deleteAgentTool(agentToolId: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/agent-documents/\(agentToolId)") + //Remove Tool + ///Remove tool from agent + public func removeToolFromAgent(agentId: String, toolId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/agents/\(agentId)/tools/\(toolId)") guard let responseData = data as? [String: Any], let success = responseData["data"] as? [String: Any] else { throw SuperagentError.requestFailed } #if DEBUG - Swift.print("deleteAgentTool result: \(success)") + Swift.print("remove tool from agent result: \(success)") #endif return success } - //Tools - ///Returns a specific tool - public func getTool(id: String) async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/tools/\(id)") - - guard let responseData = data as? [String: Any], - let toolData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } -#if DEBUG - Swift.print("getTool result: \(toolData)") -#endif - return toolData - } - - ///Delete tool - public func deleteTool(id: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/tools/\(id)") + //List Datasources + ///List agent datasources + public func listAgentDatasources(agentId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agents/\(agentId)/datasources") guard let responseData = data as? [String: Any], - let toolData = responseData["data"] as? [String: Any] else { + let agentDatasources = responseData["data"] as? [String: Any] else { throw SuperagentError.requestFailed } #if DEBUG - Swift.print("deleteTool result: \(toolData)") + Swift.print("deleteAgentTool result: \(agentDatasources)") #endif - return toolData + return agentDatasources } - ///Lists all tools - public func listTools() async throws -> [[String: Any]] { - let data = try await request(method: .get, endpoint: "/tools") + //Add Datasource + ///Add datasource to agent + public func addDatasourceToAgent(agentId: String, datasourceId: String) async throws -> [String: Any] { + let data = try await request(method: .post, endpoint: "/agents/\(agentId)/datasources", data: ["datasourceId": datasourceId]) guard let responseData = data as? [String: Any], - let toolData = responseData["data"] as? [[String: Any]] else { + let agentDatasources = responseData["data"] as? [String: Any] else { throw SuperagentError.failedToRetrieve } #if DEBUG - Swift.print("listTools result: \(toolData)") + Swift.print("add datasource to agent result: \(agentDatasources)") #endif - return toolData + return agentDatasources } - ///Create a new tool - public func createTool(tool: Tool) async throws -> [String: Any] { - var payload: [String: Any] = ["name": tool.name, "type": tool.type] - if let metadata = tool.metadata { - payload["metadata"] = metadata - } - let data = try await request(method: .post, endpoint: "/tools", data: payload) + //Remove Datasource + ///Remove datasource from agent + public func removeDatasourceFromAgent(agentId: String, datasourceId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/agents/\(agentId)/datasources/\(datasourceId)") guard let responseData = data as? [String: Any], - let toolData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToCreate + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.requestFailed } #if DEBUG - Swift.print("createTool result: \(toolData)") + Swift.print("remove datasource from agent result: \(success)") #endif - return toolData + return success } - //Tags - ///Returns a specific tag - public func getTag(id: String) async throws -> [String: Any] { - let data = try await request(method: .get, endpoint: "/tags/\(id)") - - guard let responseData = data as? [String: Any], - let tagData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToRetrieve - } -#if DEBUG - Swift.print("getTag result: \(tagData)") -#endif - return tagData - } - - ///Delete tool - public func deleteTag(id: String) async throws -> [String: Any] { - let data = try await request(method: .delete, endpoint: "/tags/\(id)") + //List Runs + ///List agent runs + public func listRuns(agentId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/agents/\(agentId)/runs") guard let responseData = data as? [String: Any], - let tagData = responseData["data"] as? [String: Any] else { + let agentRuns = responseData["data"] as? [String: Any] else { throw SuperagentError.requestFailed } #if DEBUG - Swift.print("deleteTag result: \(tagData)") + Swift.print("List agent runs result: \(agentRuns)") #endif - return tagData + return agentRuns } - - ///Lists all tools - public func listTags() async throws -> [[String: Any]] { - let data = try await request(method: .get, endpoint: "/tags") + + //MARK: - LLM + + //List + ///List all LLMs + public func listLLMs() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/llms") guard let responseData = data as? [String: Any], - let tagsData = responseData["data"] as? [[String: Any]] else { + let llms = responseData["data"] as? [String: Any] else { throw SuperagentError.failedToRetrieve } -#if DEBUG - Swift.print("listTagss result: \(tagsData)") -#endif - return tagsData - } - ///Create a new tool - public func createTag(tag: Tag) async throws -> [String: Any] { - var payload: [String: Any] = ["name": tag.name, "type": tag.color, "userId": tag.userId ?? ""] - let data = try await request(method: .post, endpoint: "/tags", data: payload) - guard let responseData = data as? [String: Any], - let tagData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToCreate - } #if DEBUG - Swift.print("createTag result: \(tagData)") + Swift.print("list all LLMs result: \(llms)") #endif - return tagData - } - - ///Patch a tag - public func updateTag(id: String, newTag: Tag) async throws -> [String: Any] { - var payload: [String: Any] = ["name": newTag.name, "type": newTag.color] - let data = try await request(method: .post, endpoint: "/tags/\(id)", data: payload) - guard let responseData = data as? [String: Any], - let tagData = responseData["data"] as? [String: Any] else { - throw SuperagentError.failedToUpdate - } -#if DEBUG - Swift.print("updateTag result: \(tagData)") -#endif - return tagData + return llms } -} - + + //Create + ///Create a new LLM + From fa711ef8725253385f769c9f00b10dfd64f288d1 Mon Sep 17 00:00:00 2001 From: Simon Weniger Date: Tue, 19 Sep 2023 20:51:18 +0200 Subject: [PATCH 3/3] add remaining functions --- Sources/Models/Agent.swift | 2 - .../Models/AnyOfValidationErrorLocItems.swift | 16 - Sources/Models/ApiToken.swift | 23 - Sources/Models/Datasource.swift | 24 + Sources/Models/Document.swift | 66 --- Sources/Models/HTTPValidationError.swift | 20 - Sources/Models/LLM.swift | 19 + Sources/Models/Prompt.swift | 28 - Sources/Models/SignIn.swift | 22 - Sources/Models/SignUp.swift | 26 - Sources/Models/String+Error.swift | 12 - Sources/Models/Tag.swift | 30 -- Sources/Models/Tool.swift | 26 +- Sources/Models/ValidationError.swift | 24 - Sources/Models/WorkflowStep.swift | 24 + Sources/main.swift | 482 +++++++++++++++++- 16 files changed, 555 insertions(+), 289 deletions(-) delete mode 100644 Sources/Models/AnyOfValidationErrorLocItems.swift delete mode 100644 Sources/Models/ApiToken.swift create mode 100644 Sources/Models/Datasource.swift delete mode 100644 Sources/Models/Document.swift delete mode 100644 Sources/Models/HTTPValidationError.swift create mode 100644 Sources/Models/LLM.swift delete mode 100644 Sources/Models/Prompt.swift delete mode 100644 Sources/Models/SignIn.swift delete mode 100644 Sources/Models/SignUp.swift delete mode 100644 Sources/Models/String+Error.swift delete mode 100644 Sources/Models/Tag.swift delete mode 100644 Sources/Models/ValidationError.swift create mode 100644 Sources/Models/WorkflowStep.swift diff --git a/Sources/Models/Agent.swift b/Sources/Models/Agent.swift index febcc1e..a650038 100644 --- a/Sources/Models/Agent.swift +++ b/Sources/Models/Agent.swift @@ -6,8 +6,6 @@ import Foundation - - public struct Agent: Codable { public var isActive: Bool diff --git a/Sources/Models/AnyOfValidationErrorLocItems.swift b/Sources/Models/AnyOfValidationErrorLocItems.swift deleted file mode 100644 index 5d53c94..0000000 --- a/Sources/Models/AnyOfValidationErrorLocItems.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// AnyOfValidationErrorLocItems.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct AnyOfValidationErrorLocItems: Codable { - - - - -} diff --git a/Sources/Models/ApiToken.swift b/Sources/Models/ApiToken.swift deleted file mode 100644 index a224a0e..0000000 --- a/Sources/Models/ApiToken.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// ApiToken.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct ApiToken: Codable { - - public var _description: String - - public init(_description: String) { - self._description = _description - } - - public enum CodingKeys: String, CodingKey { - case _description = "description" - } - -} diff --git a/Sources/Models/Datasource.swift b/Sources/Models/Datasource.swift new file mode 100644 index 0000000..55fd644 --- /dev/null +++ b/Sources/Models/Datasource.swift @@ -0,0 +1,24 @@ +// +// Datasource.swift +// +// +// Created by Simon Weniger (Aiden Technologies) on 19.09.23. +// + +import Foundation + +public struct Datasource { + + public var name: String + public var description: String + public var type: String + public var url: String + public var metadata: [String: Any]? + + public init(name: String, description: String, type: String, url: String, metadata: [String: Any]? = nil) { + self.name = name + self.description = description + self.type = type + self.url = url + } +} diff --git a/Sources/Models/Document.swift b/Sources/Models/Document.swift deleted file mode 100644 index 0710b4b..0000000 --- a/Sources/Models/Document.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// Document.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct Document { - - public var type: String - public var url: String? - public var description: String? - public var content: String - public var name: String - public var authorization: Any? - public var metadata: Any? - public var fromPage: Int? - public var toPage: Int? - public var splitter: Splitter? - - public init(type: String, url: String? = nil, name: String, description: String, content: String, authorization: Any? = nil, metadata: Any? = nil, fromPage: Int? = nil, toPage: Int? = nil, splitter: Splitter? = nil) { - self.type = type - self.url = url - self.description = description - self.content = content - self.name = name - self.authorization = authorization - self.metadata = metadata - self.fromPage = fromPage - self.toPage = toPage - self.splitter = splitter - } - - public enum CodingKeys: String, CodingKey { - case type - case url - case name - case description - case content - case authorization - case metadata - case fromPage = "from_page" - case toPage = "to_page" - case splitter - } - - public struct Splitter: Codable { - public var type: String - public var chunkSize: Int - public var chunkOverlap: Int - - public init(type: String, chunkSize: Int, chunkOverlap: Int) { - self.type = type - self.chunkSize = chunkSize - self.chunkOverlap = chunkOverlap - } - public enum CodingKeys: String, CodingKey { - case type - case chunkSize = "chunk_size" - case chunkOverlap = "chunk_overlap" - } - } -} diff --git a/Sources/Models/HTTPValidationError.swift b/Sources/Models/HTTPValidationError.swift deleted file mode 100644 index 01ed838..0000000 --- a/Sources/Models/HTTPValidationError.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// HTTPValidationError.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct HTTPValidationError: Codable { - - public var detail: [ValidationError]? - - public init(detail: [ValidationError]? = nil) { - self.detail = detail - } - - -} diff --git a/Sources/Models/LLM.swift b/Sources/Models/LLM.swift new file mode 100644 index 0000000..14ea88a --- /dev/null +++ b/Sources/Models/LLM.swift @@ -0,0 +1,19 @@ +// +// LLM.swift +// +// +// Created by Simon Weniger (Aiden Technologies) on 19.09.23. +// +import Foundation + +public struct LLM { + public var provider: String + public var apiKey: String + public var options: [String: Any]? + + public init(provider: String, apiKey: String, options: [String: Any]? = nil) { + self.provider = provider + self.apiKey = apiKey + self.options = options + } +} diff --git a/Sources/Models/Prompt.swift b/Sources/Models/Prompt.swift deleted file mode 100644 index 3818490..0000000 --- a/Sources/Models/Prompt.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Prompt.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - -public struct Prompt: Decodable { - - public var name: String - public var inputVariables: [String] - public var template: String - - public enum CodingKeys: String, CodingKey { - case name = "name" - case inputVariables = "input_variables" - case template = "template" - } - - public init(name: String, inputVariables: [String], template: String) { - self.name = name - self.inputVariables = inputVariables - self.template = template - } - -} diff --git a/Sources/Models/SignIn.swift b/Sources/Models/SignIn.swift deleted file mode 100644 index 3015f84..0000000 --- a/Sources/Models/SignIn.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// SignIn.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct SignIn: Codable { - - public var email: String - public var password: String - - public init(email: String, password: String) { - self.email = email - self.password = password - } - - -} diff --git a/Sources/Models/SignUp.swift b/Sources/Models/SignUp.swift deleted file mode 100644 index 7f2b078..0000000 --- a/Sources/Models/SignUp.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// SignUp.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct SignUp { - - public var email: String - public var password: String - public var name: String? - public var metadata: Any? - - public init(email: String, password: String, name: String? = nil, metadata: Any? = nil) { - self.email = email - self.password = password - self.name = name - self.metadata = metadata - } - - -} diff --git a/Sources/Models/String+Error.swift b/Sources/Models/String+Error.swift deleted file mode 100644 index 4b53b25..0000000 --- a/Sources/Models/String+Error.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// String+Error.swift -// -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - -extension String: LocalizedError { - public var errorDescription: String? { return self } -} diff --git a/Sources/Models/Tag.swift b/Sources/Models/Tag.swift deleted file mode 100644 index 4ee47f6..0000000 --- a/Sources/Models/Tag.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// File.swift -// -// -// Created by vonweniger on 21.07.23. -// - -import Foundation - - - -public struct Tag { - - public var name: String - public var color: String - public var userId: String? - - public init(name: String, color: String, userId: String?) { - self.name = name - self.color = color - self.userId = color - } - - public enum CodingKeys: String, CodingKey { - case name - case color - case userId - } - -} diff --git a/Sources/Models/Tool.swift b/Sources/Models/Tool.swift index b490cc0..607289a 100644 --- a/Sources/Models/Tool.swift +++ b/Sources/Models/Tool.swift @@ -1,35 +1,25 @@ // // Tool.swift // -// Created by Simon Weniger on 09.07.23. +// Created by Simon Weniger (Aiden Technologies) on 09.07.23. // import Foundation - - public struct Tool { public var name: String + public var description: String public var type: String - public var _description: String - public var authorization: Any? - public var metadata: Any? + public var metadata: [String : Any]? + public var returnDirect: Bool? - public init(name: String, type: String, _description: String, authorization: Any? = nil, metadata: Any? = nil) { + public init(name: String, description: String, type: String, metadata: [String: Any]? = nil, returnDirect: Bool? = nil) { self.name = name + self.description = description self.type = type - self._description = _description - self.authorization = authorization self.metadata = metadata + self.returnDirect = returnDirect } - - public enum CodingKeys: String, CodingKey { - case name - case type - case _description = "description" - case authorization - case metadata - } - + } diff --git a/Sources/Models/ValidationError.swift b/Sources/Models/ValidationError.swift deleted file mode 100644 index 9c91f5d..0000000 --- a/Sources/Models/ValidationError.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ValidationError.swift -// -// Created by Simon Weniger on 09.07.23. -// - -import Foundation - - - -public struct ValidationError: Codable { - - public var loc: [AnyOfValidationErrorLocItems] - public var msg: String - public var type: String - - public init(loc: [AnyOfValidationErrorLocItems], msg: String, type: String) { - self.loc = loc - self.msg = msg - self.type = type - } - - -} diff --git a/Sources/Models/WorkflowStep.swift b/Sources/Models/WorkflowStep.swift new file mode 100644 index 0000000..e8d62b9 --- /dev/null +++ b/Sources/Models/WorkflowStep.swift @@ -0,0 +1,24 @@ +// +// Workflow.swift +// +// +// Created by Simon Weniger (Aiden Technologies) on 19.09.23. +// + +import Foundation + +public struct WorkflowStep { + + public var order: Int + public var agentId: String + public var input: String + public var output: String + + public init(order: Int, agentId: String, input: String, output: String) { + self.order = order + self.agentId = agentId + self.input = input + self.output = output + } + +} diff --git a/Sources/main.swift b/Sources/main.swift index 4cb5873..225dea9 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -23,7 +23,6 @@ enum SuperagentError: Error { case failedToCreate } -@available(macOS 12.0, *) public struct SuperagentSDK { public var baseUrl: String @@ -152,7 +151,7 @@ public struct SuperagentSDK { "llmModel": newAgent.llmModel, "description": newAgent.description, "avatar": newAgent.avatar ?? ""] - let data = try await request(method: .post, endpoint: "/agents/\(agentId)", data: payload) + let data = try await request(method: .patch, endpoint: "/agents/\(agentId)", data: payload) guard let responseData = data as? [String: Any], let agentData = responseData["data"] as? [String: Any] else { @@ -367,4 +366,483 @@ public struct SuperagentSDK { //Create ///Create a new LLM + public func createLLM(provider: String, apiKey: String, options: [String: Any]?) async throws -> [String: Any] { + var payload: [String: Any] = ["provider": provider, "apiKey": apiKey, "options": options as Any] + + let data = try await request(method: .post, endpoint: "/llms", data: payload) + + guard let responseData = data as? [String: Any], + let llm = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("create new llm result: \(llm)") +#endif + + return llm + } + + //Get + ///Get a single LLM + public func getLLM(llmId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/llms/\(llmId)") + + guard let responseData = data as? [String: Any], + let llm = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("get LLM result: \(llm)") +#endif + + return llm + } + + //Update + ///Patch an LLM + public func createLLM(llmId: String ,provider: String, apiKey: String, options: [String: Any]?) async throws -> [String: Any] { + var payload: [String: Any] = ["provider": provider, "apiKey": apiKey] + + if let options = options { + payload["options"] = options + } else { + payload["options"] = nil + } + + let data = try await request(method: .patch, endpoint: "/llms/\(llmId)", data: payload) + + guard let responseData = data as? [String: Any], + let llm = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("create new llm result: \(llm)") +#endif + + return llm + } + + //MARK: - API User + + //Create + ///Create a new API user + public func createNewApiUser() async throws -> [String: Any] { + let data = try await request(method: .post, endpoint: "/api-users") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("create new API user result: \(success)") +#endif + + return success + } + + //Get + ///Get a single api user + public func getApiUser() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/api-users/me") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("get API user result: \(success)") +#endif + + return success + } + + //Delete + ///Delete an api user + public func deleteApiUser() async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/api-users/me") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("delete API user result: \(success)") +#endif + + return success + } + + //MARK: - Datasource + + //List + ///List all datasources + public func listDatasources() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/datasources") + + guard let responseData = data as? [String: Any], + let datasources = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("list datasources result: \(datasources)") +#endif + + return datasources + } + //Create + ///Create a new datasource + public func createDatasource(datasource: Datasource) async throws -> [String: Any] { + var payload: [String: Any] = ["name": datasource.name, + "description": datasource.description, + "type": datasource.type, + "url": datasource.url, + "metadata": datasource.metadata as Any] + + let data = try await request(method: .post, endpoint: "/datasources", data: payload) + + guard let responseData = data as? [String: Any], + let llm = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("create new llm result: \(llm)") +#endif + + return llm + } + + //Get + ///Get a specific datasource + public func getDatasource(datasourceId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/datasources/\(datasourceId)") + + guard let responseData = data as? [String: Any], + let datasource = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("get datasource result: \(datasource)") +#endif + + return datasource + } + + //Update + ///Update a specific datasource + public func updateDatasource(datasourceId: String , newDatasource: Datasource) async throws -> [String: Any] { + var payload: [String: Any] = ["name": newDatasource.name, + "description": newDatasource.description, + "type": newDatasource.type, + "url": newDatasource.url] + + if let metadata = newDatasource.metadata { + payload["metadata"] = metadata + } else { + payload["metadata"] = nil + } + + let data = try await request(method: .patch, endpoint: "/datasources/\(datasourceId)", data: payload) + + guard let responseData = data as? [String: Any], + let datasource = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("update datasource result: \(datasource)") +#endif + + return datasource + } + + //Delete + ///Delete a specific datasource + public func deleteDatasource(datasourceId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/datasources/\(datasourceId)") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("delete Datasource result: \(success)") +#endif + + return success + } + + //MARK: - Tool + + //List + ///List all tools + public func listTools() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/tools") + + guard let responseData = data as? [String: Any], + let tools = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("list tools result: \(tools)") +#endif + + return tools + } + + //Create + ///Create a new tool + public func createTool(tool: Tool) async throws -> [String: Any] { + var payload: [String: Any] = ["name": tool.name, + "description": tool.description, + "type": tool.type, + "metadata": tool.metadata as Any, + "returnDirect": tool.returnDirect as Any] + + let data = try await request(method: .post, endpoint: "/tools", data: payload) + + guard let responseData = data as? [String: Any], + let tool = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("create new tool result: \(tool)") +#endif + + return tool + } + + //Get + ///Get a specific tool + public func getTool(toolId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/tool/\(toolId)") + + guard let responseData = data as? [String: Any], + let tool = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("get tool result: \(tool)") +#endif + + return tool + } + + //Update + ///Update a specific tool + public func updateTool(toolId: String , newTool: Tool) async throws -> [String: Any] { + var payload: [String: Any] = ["name": newTool.name, + "description": newTool.description, + "type": newTool.type, + "metadata": newTool.metadata as Any, + "returnDirect": newTool.returnDirect as Any] + + let data = try await request(method: .post, endpoint: "/tools/\(toolId)", data: payload) + + guard let responseData = data as? [String: Any], + let tool = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("create new tool result: \(tool)") +#endif + + return tool + } + + //Delete + ///Delete a specific tool + public func deleteTool(toolId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "/tools/\(toolId)") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("delete Datasource result: \(success)") +#endif + + return success + } + + //MARK: - Workflow + + //List + ///List all workflows + public func listWorkflows() async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "/workflows") + + guard let responseData = data as? [String: Any], + let workflows = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("list workflows result: \(workflows)") +#endif + + return workflows + } + + //Create + ///Create a new workflow + public func createWorkflow(name: String, description: String) async throws -> [String: Any] { + + let data = try await request(method: .post, endpoint: "workflows", data: ["name": name, "description": description]) + + guard let responseData = data as? [String: Any], + let workflow = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("create Workflow result: \(workflow)") + #endif + + return workflow + } + + //Get + ///Get a single workflow + public func getWorkflow(workflowId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "workflows/\(workflowId)") + + guard let responseData = data as? [String: Any], + let workflow = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("get Workflow result: \(workflow)") + #endif + + return workflow + } + + //Update + ///Patch a workflow + public func updateWorkflow(workflowId: String, newName: String, newDescription: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "workflows/\(workflowId)", data: ["name": newName, "description": newDescription]) + + guard let responseData = data as? [String: Any], + let workflow = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("get Workflow result: \(workflow)") + #endif + + return workflow + } + + //Delete + ///Delete a specific workflow + public func deleteWorkflow(workflowId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "workflows/\(workflowId)") + + guard let responseData = data as? [String: Any], + let workflow = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("get Workflow result: \(workflow)") + #endif + + return workflow + } + + //Invoke + ///Invoke a specific workflow + public func invokeWorkflow(workflowId: String, input: String, enableStreaming: Bool) async throws -> [String: Any] { + let data = try await request(method: .post, endpoint: "workflows/\(workflowId)", data: ["input": input, "enableStreaming": enableStreaming]) + + guard let responseData = data as? [String: Any], + let workflowResponse = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("invoke Workflow result: \(workflowResponse)") + #endif + + return workflowResponse + } + + //List Steps + ///List all steps of a workflow + public func listWorkflowSteps(workflowId: String) async throws -> [String: Any] { + let data = try await request(method: .get, endpoint: "workflows/\(workflowId)/steps") + + guard let responseData = data as? [String: Any], + let workflowSteps = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("list Workflow Steps result: \(workflowSteps)") + #endif + + return workflowSteps + } + + + //Add Step + ///Create a new workflow step + public func addWorkflowStep(workflowId: String ,workflowStep: WorkflowStep) async throws -> [String: Any] { + var payload: [String: Any] = ["order": workflowStep.order, + "agentId": workflowStep.agentId, + "input": workflowStep.input, + "output": workflowStep.output] + + let data = try await request(method: .post, endpoint: "/workflows/\(workflowId)/steps", data: payload) + + guard let responseData = data as? [String: Any], + let workflowStep = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + +#if DEBUG + Swift.print("add workflow step result: \(workflowStep)") +#endif + + return workflowStep + } + + //Delete Step + ///Delete a specific workflow step + public func deleteWorkflowStep(workflowId: String, stepId: String) async throws -> [String: Any] { + let data = try await request(method: .delete, endpoint: "workflows/\(workflowId)/steps\(stepId)") + + guard let responseData = data as? [String: Any], + let success = responseData["data"] as? [String: Any] else { + throw SuperagentError.failedToRetrieve + } + + #if DEBUG + Swift.print("delete workflow step result: \(success)") + #endif + + return success + + } + + +}