Skip to content

Commit

Permalink
feat: Support AI Agent API (box/box-codegen#531) (#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
box-sdk-build authored Jul 22, 2024
1 parent d51df9a commit fc9a00b
Show file tree
Hide file tree
Showing 30 changed files with 1,096 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .codegen.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "engineHash": "6a7e147", "specHash": "137da0d", "version": "0.3.0" }
{ "engineHash": "f6b5758", "specHash": "d36b9f0", "version": "0.3.0" }
308 changes: 308 additions & 0 deletions BoxSdkGen.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions Sources/Managers/Ai/AiManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,18 @@ public class AiManager {
return try AiResponse.deserialize(from: response.data)
}

/// Get the AI agent default config
///
/// - Parameters:
/// - queryParams: Query parameters of getAiAgentDefaultConfig method
/// - headers: Headers of getAiAgentDefaultConfig method
/// - Returns: The `AiAgentAskOrAiAgentTextGen`.
/// - Throws: The `GeneralError`.
public func getAiAgentDefaultConfig(queryParams: GetAiAgentDefaultConfigQueryParams, headers: GetAiAgentDefaultConfigHeaders = GetAiAgentDefaultConfigHeaders()) async throws -> AiAgentAskOrAiAgentTextGen {
let queryParamsMap: [String: String] = Utils.Dictionary.prepareParams(map: ["mode": Utils.Strings.toString(value: queryParams.mode), "language": Utils.Strings.toString(value: queryParams.language), "model": Utils.Strings.toString(value: queryParams.model)])
let headersMap: [String: String] = Utils.Dictionary.prepareParams(map: Utils.Dictionary.merge([:], headers.extraHeaders))
let response: FetchResponse = try await NetworkClient.shared.fetch(url: "\(self.networkSession.baseUrls.baseUrl)\("/2.0/ai_agent_default")", options: FetchOptions(method: "GET", params: queryParamsMap, headers: headersMap, responseFormat: "json", auth: self.auth, networkSession: self.networkSession))
return try AiAgentAskOrAiAgentTextGen.deserialize(from: response.data)
}

}
15 changes: 15 additions & 0 deletions Sources/Managers/Ai/GetAiAgentDefaultConfigHeaders.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation

public class GetAiAgentDefaultConfigHeaders {
/// Extra headers that will be included in the HTTP request.
public let extraHeaders: [String: String?]?

/// Initializer for a GetAiAgentDefaultConfigHeaders.
///
/// - Parameters:
/// - extraHeaders: Extra headers that will be included in the HTTP request.
public init(extraHeaders: [String: String?]? = [:]) {
self.extraHeaders = extraHeaders
}

}
27 changes: 27 additions & 0 deletions Sources/Managers/Ai/GetAiAgentDefaultConfigQueryParams.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation

public class GetAiAgentDefaultConfigQueryParams {
/// The mode to filter the agent config to return.
public let mode: GetAiAgentDefaultConfigQueryParamsModeField

/// The ISO language code to return the agent config for.
/// If the language is not supported the default agent config is returned.
public let language: String?

/// The model to return the default agent config for.
public let model: String?

/// Initializer for a GetAiAgentDefaultConfigQueryParams.
///
/// - Parameters:
/// - mode: The mode to filter the agent config to return.
/// - language: The ISO language code to return the agent config for.
/// If the language is not supported the default agent config is returned.
/// - model: The model to return the default agent config for.
public init(mode: GetAiAgentDefaultConfigQueryParamsModeField, language: String? = nil, model: String? = nil) {
self.mode = mode
self.language = language
self.model = model
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation

public enum GetAiAgentDefaultConfigQueryParamsModeField: String, CodableStringEnum {
case ask
case textGen = "text_gen"
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class CreateGroupMembershipRequestBody: Codable {
/// Setting these permissions overwrites the default
/// access levels of an admin.
///
/// Specifying a value of "null" for this object will disable
/// Specifying a value of `null` for this object will disable
/// all configurable permissions. Specifying permissions will set
/// them accordingly, omitted permissions will be enabled by default.
public let configurablePermissions: [String: Bool]?
Expand All @@ -42,7 +42,7 @@ public class CreateGroupMembershipRequestBody: Codable {
/// Setting these permissions overwrites the default
/// access levels of an admin.
///
/// Specifying a value of "null" for this object will disable
/// Specifying a value of `null` for this object will disable
/// all configurable permissions. Specifying permissions will set
/// them accordingly, omitted permissions will be enabled by default.
public init(user: CreateGroupMembershipRequestBodyUserField, group: CreateGroupMembershipRequestBodyGroupField, role: CreateGroupMembershipRequestBodyRoleField? = nil, configurablePermissions: [String: Bool]? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class UpdateGroupMembershipByIdRequestBody: Codable {
/// Setting these permissions overwrites the default
/// access levels of an admin.
///
/// Specifying a value of "null" for this object will disable
/// Specifying a value of `null` for this object will disable
/// all configurable permissions. Specifying permissions will set
/// them accordingly, omitted permissions will be enabled by default.
public let configurablePermissions: [String: Bool]?
Expand All @@ -32,7 +32,7 @@ public class UpdateGroupMembershipByIdRequestBody: Codable {
/// Setting these permissions overwrites the default
/// access levels of an admin.
///
/// Specifying a value of "null" for this object will disable
/// Specifying a value of `null` for this object will disable
/// all configurable permissions. Specifying permissions will set
/// them accordingly, omitted permissions will be enabled by default.
public init(role: UpdateGroupMembershipByIdRequestBodyRoleField? = nil, configurablePermissions: [String: Bool]? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class UpdateRetentionPolicyByIdRequestBody: Codable {
/// which will lift the retention policy from the content,
/// allowing it to be deleted by users,
/// once the retention policy has expired.
/// You can use "null" if you don't want to change `disposition_action`.
/// You can use `null` if you don't want to change `disposition_action`.
public let dispositionAction: String?

/// Specifies the retention type:
Expand Down Expand Up @@ -89,7 +89,7 @@ public class UpdateRetentionPolicyByIdRequestBody: Codable {
/// which will lift the retention policy from the content,
/// allowing it to be deleted by users,
/// once the retention policy has expired.
/// You can use "null" if you don't want to change `disposition_action`.
/// You can use `null` if you don't want to change `disposition_action`.
/// - retentionType: Specifies the retention type:
///
/// * `modifiable`: You can modify the retention policy. For example,
Expand Down
58 changes: 58 additions & 0 deletions Sources/Schemas/AiAgentAsk/AiAgentAsk.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Foundation

/// The AI agent used to handle queries.
public class AiAgentAsk: Codable {
private enum CodingKeys: String, CodingKey {
case type
case longText = "long_text"
case basicText = "basic_text"
case longTextMulti = "long_text_multi"
case basicTextMulti = "basic_text_multi"
}

/// The type of AI agent used to handle queries.
public let type: AiAgentAskTypeField?

public let longText: AiAgentLongTextTool?

public let basicText: AiAgentBasicTextToolAsk?

public let longTextMulti: AiAgentLongTextTool?

public let basicTextMulti: AiAgentBasicTextToolAsk?

/// Initializer for a AiAgentAsk.
///
/// - Parameters:
/// - type: The type of AI agent used to handle queries.
/// - longText:
/// - basicText:
/// - longTextMulti:
/// - basicTextMulti:
public init(type: AiAgentAskTypeField? = nil, longText: AiAgentLongTextTool? = nil, basicText: AiAgentBasicTextToolAsk? = nil, longTextMulti: AiAgentLongTextTool? = nil, basicTextMulti: AiAgentBasicTextToolAsk? = nil) {
self.type = type
self.longText = longText
self.basicText = basicText
self.longTextMulti = longTextMulti
self.basicTextMulti = basicTextMulti
}

required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
type = try container.decodeIfPresent(AiAgentAskTypeField.self, forKey: .type)
longText = try container.decodeIfPresent(AiAgentLongTextTool.self, forKey: .longText)
basicText = try container.decodeIfPresent(AiAgentBasicTextToolAsk.self, forKey: .basicText)
longTextMulti = try container.decodeIfPresent(AiAgentLongTextTool.self, forKey: .longTextMulti)
basicTextMulti = try container.decodeIfPresent(AiAgentBasicTextToolAsk.self, forKey: .basicTextMulti)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(type, forKey: .type)
try container.encodeIfPresent(longText, forKey: .longText)
try container.encodeIfPresent(basicText, forKey: .basicText)
try container.encodeIfPresent(longTextMulti, forKey: .longTextMulti)
try container.encodeIfPresent(basicTextMulti, forKey: .basicTextMulti)
}

}
5 changes: 5 additions & 0 deletions Sources/Schemas/AiAgentAsk/AiAgentAskTypeField.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public enum AiAgentAskTypeField: String, CodableStringEnum {
case aiAgentAsk = "ai_agent_ask"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Foundation

public enum AiAgentAskOrAiAgentTextGen: Codable {
case aiAgentAsk(AiAgentAsk)
case aiAgentTextGen(AiAgentTextGen)

private enum DiscriminatorCodingKey: String, CodingKey {
case type
}

public init(from decoder: Decoder) throws {
if let container = try? decoder.container(keyedBy: DiscriminatorCodingKey.self) {
if let discriminator_0 = try? container.decode(String.self, forKey: .type) {
switch discriminator_0 {
case "ai_agent_ask":
if let content = try? AiAgentAsk(from: decoder) {
self = .aiAgentAsk(content)
return
}

case "ai_agent_text_gen":
if let content = try? AiAgentTextGen(from: decoder) {
self = .aiAgentTextGen(content)
return
}

default:
throw DecodingError.typeMismatch(AiAgentAskOrAiAgentTextGen.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "The Decoded object contains an unexpected value for key type"))

}
}

}

throw DecodingError.typeMismatch(AiAgentAskOrAiAgentTextGen.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "The type of the decoded object cannot be determined."))

}

public func encode(to encoder: Encoder) throws {
switch self {
case .aiAgentAsk(let aiAgentAsk):
try aiAgentAsk.encode(to: encoder)
case .aiAgentTextGen(let aiAgentTextGen):
try aiAgentTextGen.encode(to: encoder)
}
}

}
47 changes: 47 additions & 0 deletions Sources/Schemas/AiAgentBasicGenTool/AiAgentBasicGenTool.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Foundation

/// AI agent basic tool used to generate text.
public class AiAgentBasicGenTool: AiAgentLongTextTool {
private enum CodingKeys: String, CodingKey {
case contentTemplate = "content_template"
}

/// How the content should be included in a request to the LLM.
/// When passing this parameter, you must include `{content}`.
public let contentTemplate: String?

/// Initializer for a AiAgentBasicGenTool.
///
/// - Parameters:
/// - model: The model to be used for the AI Agent for basic text.
/// - systemMessage: System messages try to help the LLM "understand" its role and what it is supposed to do.
/// This parameter requires using `{current_date}`.
/// - promptTemplate: The prompt template contains contextual information of the request and the user prompt.
///
/// When using the `prompt_template` parameter, you **must include** input for `{user_question}`.
/// Inputs for `{current_date}` and`{content}` are optional, depending on the use.
/// - numTokensForCompletion: The number of tokens for completion.
/// - llmEndpointParams:
/// - embeddings:
/// - contentTemplate: How the content should be included in a request to the LLM.
/// When passing this parameter, you must include `{content}`.
public init(model: String? = nil, systemMessage: String? = nil, promptTemplate: String? = nil, numTokensForCompletion: Int64? = nil, llmEndpointParams: AiLlmEndpointParamsGoogleOrAiLlmEndpointParamsOpenAi? = nil, embeddings: AiAgentLongTextToolEmbeddingsField? = nil, contentTemplate: String? = nil) {
self.contentTemplate = contentTemplate

super.init(model: model, systemMessage: systemMessage, promptTemplate: promptTemplate, numTokensForCompletion: numTokensForCompletion, llmEndpointParams: llmEndpointParams, embeddings: embeddings)
}

required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
contentTemplate = try container.decodeIfPresent(String.self, forKey: .contentTemplate)

try super.init(from: decoder)
}

public override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(contentTemplate, forKey: .contentTemplate)
try super.encode(to: encoder)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Foundation

/// AI agent tool used to handle basic text.
public class AiAgentBasicTextToolAsk: Codable {
private enum CodingKeys: String, CodingKey {
case model
case systemMessage = "system_message"
case promptTemplate = "prompt_template"
case numTokensForCompletion = "num_tokens_for_completion"
case llmEndpointParams = "llm_endpoint_params"
}

/// The model used for the AI Agent for basic text.
public let model: String?

/// System messages try to help the LLM "understand" its role and what it is supposed to do.
public let systemMessage: String?

/// The prompt template contains contextual information of the request and the user prompt.
///
/// When passing `prompt_template` parameters, you **must include** inputs for `{current_date}`, `{user_question}`, and `{content}`.
public let promptTemplate: String?

/// The number of tokens for completion.
public let numTokensForCompletion: Int64?

/// The parameters for the LLM endpoint specific to OpenAI / Google models.
public let llmEndpointParams: AiLlmEndpointParamsGoogleOrAiLlmEndpointParamsOpenAi?

/// Initializer for a AiAgentBasicTextToolAsk.
///
/// - Parameters:
/// - model: The model used for the AI Agent for basic text.
/// - systemMessage: System messages try to help the LLM "understand" its role and what it is supposed to do.
/// - promptTemplate: The prompt template contains contextual information of the request and the user prompt.
///
/// When passing `prompt_template` parameters, you **must include** inputs for `{current_date}`, `{user_question}`, and `{content}`.
/// - numTokensForCompletion: The number of tokens for completion.
/// - llmEndpointParams: The parameters for the LLM endpoint specific to OpenAI / Google models.
public init(model: String? = nil, systemMessage: String? = nil, promptTemplate: String? = nil, numTokensForCompletion: Int64? = nil, llmEndpointParams: AiLlmEndpointParamsGoogleOrAiLlmEndpointParamsOpenAi? = nil) {
self.model = model
self.systemMessage = systemMessage
self.promptTemplate = promptTemplate
self.numTokensForCompletion = numTokensForCompletion
self.llmEndpointParams = llmEndpointParams
}

required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
model = try container.decodeIfPresent(String.self, forKey: .model)
systemMessage = try container.decodeIfPresent(String.self, forKey: .systemMessage)
promptTemplate = try container.decodeIfPresent(String.self, forKey: .promptTemplate)
numTokensForCompletion = try container.decodeIfPresent(Int64.self, forKey: .numTokensForCompletion)
llmEndpointParams = try container.decodeIfPresent(AiLlmEndpointParamsGoogleOrAiLlmEndpointParamsOpenAi.self, forKey: .llmEndpointParams)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(model, forKey: .model)
try container.encodeIfPresent(systemMessage, forKey: .systemMessage)
try container.encodeIfPresent(promptTemplate, forKey: .promptTemplate)
try container.encodeIfPresent(numTokensForCompletion, forKey: .numTokensForCompletion)
try container.encodeIfPresent(llmEndpointParams, forKey: .llmEndpointParams)
}

}
Loading

0 comments on commit fc9a00b

Please sign in to comment.