diff --git a/.castiron.stats.yml b/.castiron.stats.yml index 9770ecf28..3cafec131 100644 --- a/.castiron.stats.yml +++ b/.castiron.stats.yml @@ -1,8 +1,8 @@ schema_version: 1 -generation_id: c67fe055-5fef-4490-a93e-212d8568459a -openapi_spec_hash: 9585fb5cd9d39a73de012b8de53b088a -openapi_transformed_spec_hash: c497de66b4332c26986df2cb087da34a -config_hash: 075dc8d5c682945dd2c56e77607736a1 -codegen_sha: c9f081c5aff42abd96fb8a2bb6aa0cb3edb29ce0 -codegen_hash: 1752270cf5c4363ac5590798437d9abe9a17fc97188f305211630acb2dc1ce4d -public_codegen_sha: 9b09f5dcd2bec975a9539d4d08f4b87358de65e8 +generation_id: 01c83579-70ea-4914-8768-899cec38d48f +openapi_spec_hash: f21b711c644bd7acb83c4a35be5f89b5 +openapi_transformed_spec_hash: 9d23bc992f6c476d92ff2a1768ed1b17 +config_hash: ed29aaecbd1993a4cd3a714b00bc39d2 +codegen_sha: af3150cf8c7087803e8c8f654c8caed71ece8dc1 +codegen_hash: 3b88e4e434f203fd5f6acdc953dfaf989d42a0d2fdb649783be2828d9839c47f +public_codegen_sha: d0d04b12471f991e99e1cac4262bb8f467d43b1b diff --git a/api_reference/openapi.transformed.yml b/api_reference/openapi.transformed.yml index 9cd67be44..66338069b 100644 --- a/api_reference/openapi.transformed.yml +++ b/api_reference/openapi.transformed.yml @@ -30153,6 +30153,171 @@ paths: "total_tokens": 42 } } + /agents/environments: + get: + operationId: listAgentEnvironments + summary: List agent environments + description: Lists OpenAI-hosted environments owned by the authenticated principal. Requires access to the prewarming beta. + tags: + - Agents + parameters: + - name: limit + in: query + required: false + schema: + type: integer + format: int64 + minimum: 1 + maximum: 100 + default: 20 + description: The maximum number of environments to return, between 1 and 100. Defaults to 20. + - name: order + in: query + required: false + schema: + $ref: '#/components/schemas/ListOrderParam' + default: desc + description: The order in which environments are returned. Defaults to `desc`. + - name: after + in: query + required: false + schema: + type: string + minLength: 0 + maxLength: 1048576 + description: Return environments after this environment ID in the selected order. + - name: type + in: query + required: false + schema: + $ref: '#/components/schemas/EnvironmentTypeParam' + description: The hosting type to list. Defaults to `openai_hosted`. + responses: + '200': + description: A page of owned environments. + content: + application/json: + schema: + $ref: '#/components/schemas/AgentEnvironmentListResource' + description: An ID-paginated list of owned environments. + '400': + description: The request was invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '401': + description: Authentication or project context was missing. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '403': + description: The API key lacks the required permission. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '404': + description: The requested environment or referenced resource was not found. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '409': + description: The request conflicted with the current environment state. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '500': + description: An internal error occurred. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '503': + description: The service is temporarily unavailable. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + post: + operationId: createAgentEnvironment + summary: Create an agent environment + description: Creates an OpenAI-hosted environment before creating a session. Requires access to the prewarming beta. + tags: + - Agents + parameters: + - name: Idempotency-Key + in: header + required: false + schema: + type: string + minLength: 1 + maxLength: 256 + description: Deduplicates creation for 24 hours within the authenticated organization, project, and creator. Retry the same JSON parameters with the same key to retrieve the original environment in its current state. Different parameters or an incomplete hosted creation return 409. Deleted environments are not recreated. After retention expires, the key may create a new environment. Without this header, each request creates a new environment. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAgentEnvironmentParams' + required: true + responses: + '201': + description: The created OpenAI-hosted environment. + content: + application/json: + schema: + $ref: '#/components/schemas/PublicEnvironmentResource' + '400': + description: The request was invalid. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '401': + description: Authentication or project context was missing. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '403': + description: The API key lacks the required permission. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '404': + description: The requested environment or referenced resource was not found. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '409': + description: The request conflicted with the current environment state. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '429': + description: The request exceeded a rate or capacity limit. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '500': + description: An internal error occurred. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' + '503': + description: The service is temporarily unavailable. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse-2' /agents/environments/{environment_id}: get: operationId: retrieveAgentEnvironment @@ -36023,6 +36188,36 @@ paths: "input_tokens": 11 } webhooks: + agent_environment_failed: + post: + description: | + Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to a session. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookAgentEnvironmentFailed' + responses: + '200': + description: | + Return a 200 status code to acknowledge receipt of the event. Non-200 + status codes will be retried. + agent_environment_ready: + post: + description: | + Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a session. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookAgentEnvironmentReady' + responses: + '200': + description: | + Return a 200 status code to acknowledge receipt of the event. Non-200 + status codes will be retried. agent_session_action_required: post: description: | @@ -71229,6 +71424,68 @@ components: - type - status - action + WebhookAgentEnvironmentFailed: + type: object + title: agent.environment.failed + description: | + Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to a session. + allOf: + - $ref: '#/components/schemas/WebhookAgentSessionEnvelope' + - type: object + required: + - type + - data + properties: + type: + type: string + description: The event type. Always `agent.environment.failed`. + enum: + - agent.environment.failed + x-stainless-const: true + data: + $ref: '#/components/schemas/AgentEnvironmentEvent' + x-oaiMeta: + name: agent.environment.failed + group: webhook-events + example: | + { + "id": "evt_123", + "object": "event", + "created_at": 1719168000, + "type": "agent.environment.failed", + "data": {"id": "ccarenv_123"} + } + WebhookAgentEnvironmentReady: + type: object + title: agent.environment.ready + description: | + Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a session. + allOf: + - $ref: '#/components/schemas/WebhookAgentSessionEnvelope' + - type: object + required: + - type + - data + properties: + type: + type: string + description: The event type. Always `agent.environment.ready`. + enum: + - agent.environment.ready + x-stainless-const: true + data: + $ref: '#/components/schemas/AgentEnvironmentEvent' + x-oaiMeta: + name: agent.environment.ready + group: webhook-events + example: | + { + "id": "evt_123", + "object": "event", + "created_at": 1719168000, + "type": "agent.environment.ready", + "data": {"id": "ccarenv_123"} + } WebhookAgentSessionActionRequired: type: object title: agent.session.action_required @@ -80894,6 +81151,11 @@ components: - answers - usage additionalProperties: false + EnvironmentTypeParam: + type: string + enum: + - openai_hosted + description: The hosting type of an execution environment. EnvironmentTypeResource: type: string enum: @@ -80904,12 +81166,14 @@ components: type: string enum: - pending + - ready - connected - disconnected - expired - failed x-enumDescriptions: - '' + - Provisioning succeeded and the environment is available for attachment or use. - '' - '' - '' @@ -81149,6 +81413,46 @@ components: - plugins additionalProperties: false description: Safe metadata for a first-class execution environment. + AgentEnvironmentListResource: + type: object + properties: + object: + type: string + enum: + - list + default: list + x-stainless-const: true + description: The object type, which is always `list`. + data: + type: array + items: + $ref: '#/components/schemas/PublicEnvironmentResource' + minItems: 0 + maxItems: 2000 + description: The resources returned in this page, in the requested sort order. + first_id: + type: + - string + - 'null' + minLength: 0 + description: The ID of the first resource in `data`, or `null` if the page is empty. + last_id: + type: + - string + - 'null' + minLength: 0 + description: The ID of the last resource in `data`, or `null` if the page is empty. Pass this as `after` with the same order and filters. + has_more: + type: boolean + description: Whether there are more resources to retrieve after this page. + required: + - object + - data + - first_id + - last_id + - has_more + additionalProperties: false + description: A page of Agents API resources, with IDs for retrieving additional pages. ErrorBodyResource: type: object properties: @@ -81196,6 +81500,133 @@ components: - Returns resources in ascending order. - Returns resources in descending order. description: The order in which paginated resources are returned. + CreateEnvironmentParamOpenaiHosted: + type: object + properties: + type: + type: string + enum: + - openai_hosted + default: openai_hosted + x-stainless-const: true + description: The type of the object. Always `openai_hosted`. + packages: + anyOf: + - $ref: '#/components/schemas/EnvironmentPackagesParam' + - type: 'null' + description: Packages to install in the environment. Defaults to empty package lists. + setup_commands: + type: + - array + - 'null' + items: + $ref: '#/components/schemas/SetupCommandParam' + minItems: 0 + maxItems: 16 + description: Ordered, confidential setup commands. Command bodies are never returned. + network: + anyOf: + - $ref: '#/components/schemas/NetworkPolicyParam' + - type: 'null' + description: Network access policy for the environment. If omitted, the API version determines whether network access is enabled or disabled. + desktop: + anyOf: + - $ref: '#/components/schemas/DesktopParam' + - type: 'null' + description: Desktop provisioning. Omission or null inherits the template setting, or defaults to disabled. + env: + type: + - object + - 'null' + additionalProperties: + type: string + minLength: 0 + maxLength: 1048576 + propertyNames: + type: string + minLength: 1 + maxLength: 256 + minProperties: 0 + maxProperties: 1024 + description: Environment variables made available to the agent. + capability_directories: + type: + - array + - 'null' + items: + type: string + minLength: 0 + maxLength: 1048576 + minItems: 0 + maxItems: 16384 + description: Directories that contain capabilities exposed to the agent. Defaults to an empty list. + skills: + type: + - array + - 'null' + items: + $ref: '#/components/schemas/HostedSkillParam' + minItems: 0 + maxItems: 200 + description: Skills referenced by ID or provided as inline ZIP archives. Defaults to an empty list. + plugins: + type: + - array + - 'null' + items: + $ref: '#/components/schemas/HostedPluginParam' + minItems: 0 + maxItems: 32 + description: Plugins provided as inline ZIP archives. Defaults to an empty list. + files: + type: + - array + - 'null' + items: + $ref: '#/components/schemas/HostedEnvironmentFileParam' + minItems: 0 + maxItems: 50 + description: Files available before the agent starts. Defaults to an empty list. + environment_template_id: + type: string + minLength: 0 + maxLength: 64 + description: A reusable hosted template applied before inline configuration. Omitted fields inherit the template; network overrides cannot broaden its policy. + required: + - type + additionalProperties: false + description: Provision an OpenAI-hosted environment from inline configuration or a template. + CreateEnvironmentParam: + description: Configuration for a new prewarmed OpenAI-hosted environment. + discriminator: + propertyName: type + mapping: + openai_hosted: '#/components/schemas/CreateEnvironmentParamOpenaiHosted' + x-oai-discriminator-values: + - openai_hosted + anyOf: + - $ref: '#/components/schemas/CreateEnvironmentParamOpenaiHosted' + CreateAgentEnvironmentParams: + type: object + properties: + environment: + $ref: '#/components/schemas/CreateEnvironmentParam' + description: The required hosting type and its configuration. + vault_ids: + type: + - array + - 'null' + items: + type: string + minLength: 0 + maxLength: 1048576 + minItems: 0 + maxItems: 10 + description: The IDs of up to 10 vaults made available to an OpenAI-hosted environment. + required: + - environment + additionalProperties: false + description: Parameters for creating an execution environment before its sessions. EnvironmentFilePageObjectResource: type: string enum: @@ -86359,6 +86790,11 @@ components: minItems: 0 maxItems: 50 description: Files available before the agent starts. Defaults to an empty list. + environment_id: + type: string + minLength: 9 + maxLength: 256 + description: An existing prewarmed environment. Cannot be combined with a template or inline configuration. environment_template_id: type: string minLength: 0 @@ -86373,6 +86809,32 @@ components: - type additionalProperties: false description: An existing OpenAI-hosted environment or new inline/template-based hosted configuration. + not: + required: + - environment_id + anyOf: + - required: + - packages + - required: + - setup_commands + - required: + - network + - required: + - desktop + - required: + - env + - required: + - capability_directories + - required: + - skills + - required: + - plugins + - required: + - files + - required: + - environment_template_id + - required: + - container_size EnvironmentParamSelfHosted: type: object properties: @@ -89688,6 +90150,8 @@ components: - realtime.call.incoming - video.completed - video.failed + - agent.environment.ready + - agent.environment.failed - agent.session.created - agent.session.action_required - agent.session.in_progress @@ -89871,6 +90335,17 @@ components: required: - object - data + AgentEnvironmentEvent: + type: object + properties: + id: + type: string + minLength: 0 + description: The ID of the environment. + required: + - id + additionalProperties: false + description: Identifies the environment whose lifecycle changed. AgentSessionRequiredActionTypeResource: type: string enum: diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/EnvironmentParam.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/EnvironmentParam.kt index 2ea7738e5..f831ee695 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/EnvironmentParam.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/EnvironmentParam.kt @@ -294,6 +294,7 @@ private constructor( private val containerSize: JsonField, private val desktop: JsonField, private val env: JsonField, + private val environmentId: JsonField, private val environmentTemplateId: JsonField, private val files: JsonField>, private val network: JsonField, @@ -315,6 +316,9 @@ private constructor( containerSize: JsonField = JsonMissing.of(), @JsonProperty("desktop") @ExcludeMissing desktop: JsonField = JsonMissing.of(), @JsonProperty("env") @ExcludeMissing env: JsonField = JsonMissing.of(), + @JsonProperty("environment_id") + @ExcludeMissing + environmentId: JsonField = JsonMissing.of(), @JsonProperty("environment_template_id") @ExcludeMissing environmentTemplateId: JsonField = JsonMissing.of(), @@ -340,6 +344,7 @@ private constructor( containerSize, desktop, env, + environmentId, environmentTemplateId, files, network, @@ -397,6 +402,15 @@ private constructor( */ fun env(): Optional = env.getOptional("env") + /** + * An existing prewarmed environment. Cannot be combined with a template or inline + * configuration. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun environmentId(): Optional = environmentId.getOptional("environment_id") + /** * A reusable hosted template applied before inline session configuration. Omitted fields * inherit the template; network overrides cannot broaden its policy. @@ -491,6 +505,16 @@ private constructor( */ @JsonProperty("env") @ExcludeMissing fun _env(): JsonField = env + /** + * Returns the raw JSON value of [environmentId]. + * + * Unlike [environmentId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("environment_id") + @ExcludeMissing + fun _environmentId(): JsonField = environmentId + /** * Returns the raw JSON value of [environmentTemplateId]. * @@ -578,6 +602,7 @@ private constructor( private var containerSize: JsonField = JsonMissing.of() private var desktop: JsonField = JsonMissing.of() private var env: JsonField = JsonMissing.of() + private var environmentId: JsonField = JsonMissing.of() private var environmentTemplateId: JsonField = JsonMissing.of() private var files: JsonField>? = null private var network: JsonField = JsonMissing.of() @@ -595,6 +620,7 @@ private constructor( containerSize = openaiHosted.containerSize desktop = openaiHosted.desktop env = openaiHosted.env + environmentId = openaiHosted.environmentId environmentTemplateId = openaiHosted.environmentTemplateId files = openaiHosted.files.map { it.toMutableList() } network = openaiHosted.network @@ -704,6 +730,23 @@ private constructor( */ fun env(env: JsonField) = apply { this.env = env } + /** + * An existing prewarmed environment. Cannot be combined with a template or inline + * configuration. + */ + fun environmentId(environmentId: String) = environmentId(JsonField.of(environmentId)) + + /** + * Sets [Builder.environmentId] to an arbitrary JSON value. + * + * You should usually call [Builder.environmentId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun environmentId(environmentId: JsonField) = apply { + this.environmentId = environmentId + } + /** * A reusable hosted template applied before inline session configuration. Omitted * fields inherit the template; network overrides cannot broaden its policy. @@ -937,6 +980,7 @@ private constructor( containerSize, desktop, env, + environmentId, environmentTemplateId, (files ?: JsonMissing.of()).map { it.toImmutable() }, network, @@ -973,6 +1017,7 @@ private constructor( containerSize().ifPresent { it.validate() } desktop().ifPresent { it.validate() } env().ifPresent { it.validate() } + environmentId() environmentTemplateId() files().ifPresent { it.forEach { it.validate() } } network().ifPresent { it.validate() } @@ -1004,6 +1049,7 @@ private constructor( (containerSize.asKnown().getOrNull()?.validity() ?: 0) + (desktop.asKnown().getOrNull()?.validity() ?: 0) + (env.asKnown().getOrNull()?.validity() ?: 0) + + (if (environmentId.asKnown().isPresent) 1 else 0) + (if (environmentTemplateId.asKnown().isPresent) 1 else 0) + (files.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (network.asKnown().getOrNull()?.validity() ?: 0) + @@ -2225,6 +2271,7 @@ private constructor( containerSize == other.containerSize && desktop == other.desktop && env == other.env && + environmentId == other.environmentId && environmentTemplateId == other.environmentTemplateId && files == other.files && network == other.network && @@ -2242,6 +2289,7 @@ private constructor( containerSize, desktop, env, + environmentId, environmentTemplateId, files, network, @@ -2256,7 +2304,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "OpenAIHosted{type=$type, capabilityDirectories=$capabilityDirectories, containerSize=$containerSize, desktop=$desktop, env=$env, environmentTemplateId=$environmentTemplateId, files=$files, network=$network, packages=$packages, plugins=$plugins, setupCommands=$setupCommands, skills=$skills, additionalProperties=$additionalProperties}" + "OpenAIHosted{type=$type, capabilityDirectories=$capabilityDirectories, containerSize=$containerSize, desktop=$desktop, env=$env, environmentId=$environmentId, environmentTemplateId=$environmentTemplateId, files=$files, network=$network, packages=$packages, plugins=$plugins, setupCommands=$setupCommands, skills=$skills, additionalProperties=$additionalProperties}" } /** An application-hosted environment configured inline. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateParams.kt new file mode 100644 index 000000000..b3d356c10 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateParams.kt @@ -0,0 +1,2344 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.Params +import com.openai.core.checkKnown +import com.openai.core.checkRequired +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.beta.agents.HostedEnvironmentFileParam +import com.openai.models.beta.agents.HostedPluginParam +import com.openai.models.beta.agents.HostedSkillParam +import com.openai.models.beta.agents.SetupCommandParam +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Creates an OpenAI-hosted environment before creating a session. Requires access to the prewarming + * beta. + */ +class EnvironmentCreateParams +private constructor( + private val idempotencyKey: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun idempotencyKey(): Optional = Optional.ofNullable(idempotencyKey) + + /** + * The required hosting type and its configuration. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun environment(): Environment = body.environment() + + /** + * The IDs of up to 10 vaults made available to an OpenAI-hosted environment. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun vaultIds(): Optional> = body.vaultIds() + + /** + * Returns the raw JSON value of [environment]. + * + * Unlike [environment], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _environment(): JsonField = body._environment() + + /** + * Returns the raw JSON value of [vaultIds]. + * + * Unlike [vaultIds], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _vaultIds(): JsonField> = body._vaultIds() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EnvironmentCreateParams]. + * + * The following fields are required: + * ```java + * .environment() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EnvironmentCreateParams]. */ + class Builder internal constructor() { + + private var idempotencyKey: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(environmentCreateParams: EnvironmentCreateParams) = apply { + idempotencyKey = environmentCreateParams.idempotencyKey + body = environmentCreateParams.body.toBuilder() + additionalHeaders = environmentCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = environmentCreateParams.additionalQueryParams.toBuilder() + } + + fun idempotencyKey(idempotencyKey: String?) = apply { this.idempotencyKey = idempotencyKey } + + /** Alias for calling [Builder.idempotencyKey] with `idempotencyKey.orElse(null)`. */ + fun idempotencyKey(idempotencyKey: Optional) = + idempotencyKey(idempotencyKey.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [environment] + * - [vaultIds] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** The required hosting type and its configuration. */ + fun environment(environment: Environment) = apply { body.environment(environment) } + + /** + * Sets [Builder.environment] to an arbitrary JSON value. + * + * You should usually call [Builder.environment] with a well-typed [Environment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun environment(environment: JsonField) = apply { + body.environment(environment) + } + + /** The IDs of up to 10 vaults made available to an OpenAI-hosted environment. */ + fun vaultIds(vaultIds: List?) = apply { body.vaultIds(vaultIds) } + + /** Alias for calling [Builder.vaultIds] with `vaultIds.orElse(null)`. */ + fun vaultIds(vaultIds: Optional>) = vaultIds(vaultIds.getOrNull()) + + /** + * Sets [Builder.vaultIds] to an arbitrary JSON value. + * + * You should usually call [Builder.vaultIds] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun vaultIds(vaultIds: JsonField>) = apply { body.vaultIds(vaultIds) } + + /** + * Adds a single [String] to [vaultIds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addVaultId(vaultId: String) = apply { body.addVaultId(vaultId) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [EnvironmentCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .environment() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EnvironmentCreateParams = + EnvironmentCreateParams( + idempotencyKey, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + override fun _headers(): Headers = + Headers.builder() + .apply { + idempotencyKey?.let { put("Idempotency-Key", it) } + putAll(additionalHeaders) + } + .build() + + override fun _queryParams(): QueryParams = additionalQueryParams + + /** Parameters for creating an execution environment before its sessions. */ + class Body + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val environment: JsonField, + private val vaultIds: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("environment") + @ExcludeMissing + environment: JsonField = JsonMissing.of(), + @JsonProperty("vault_ids") + @ExcludeMissing + vaultIds: JsonField> = JsonMissing.of(), + ) : this(environment, vaultIds, mutableMapOf()) + + /** + * The required hosting type and its configuration. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun environment(): Environment = environment.getRequired("environment") + + /** + * The IDs of up to 10 vaults made available to an OpenAI-hosted environment. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun vaultIds(): Optional> = vaultIds.getOptional("vault_ids") + + /** + * Returns the raw JSON value of [environment]. + * + * Unlike [environment], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("environment") + @ExcludeMissing + fun _environment(): JsonField = environment + + /** + * Returns the raw JSON value of [vaultIds]. + * + * Unlike [vaultIds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("vault_ids") + @ExcludeMissing + fun _vaultIds(): JsonField> = vaultIds + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .environment() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var environment: JsonField? = null + private var vaultIds: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + environment = body.environment + vaultIds = body.vaultIds.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** The required hosting type and its configuration. */ + fun environment(environment: Environment) = environment(JsonField.of(environment)) + + /** + * Sets [Builder.environment] to an arbitrary JSON value. + * + * You should usually call [Builder.environment] with a well-typed [Environment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun environment(environment: JsonField) = apply { + this.environment = environment + } + + /** The IDs of up to 10 vaults made available to an OpenAI-hosted environment. */ + fun vaultIds(vaultIds: List?) = vaultIds(JsonField.ofNullable(vaultIds)) + + /** Alias for calling [Builder.vaultIds] with `vaultIds.orElse(null)`. */ + fun vaultIds(vaultIds: Optional>) = vaultIds(vaultIds.getOrNull()) + + /** + * Sets [Builder.vaultIds] to an arbitrary JSON value. + * + * You should usually call [Builder.vaultIds] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun vaultIds(vaultIds: JsonField>) = apply { + this.vaultIds = vaultIds.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [vaultIds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addVaultId(vaultId: String) = apply { + vaultIds = + (vaultIds ?: JsonField.of(mutableListOf())).also { + checkKnown("vaultIds", it).add(vaultId) + } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .environment() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("environment", environment), + (vaultIds ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Body = apply { + if (validated) { + return@apply + } + + environment().validate() + vaultIds() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (environment.asKnown().getOrNull()?.validity() ?: 0) + + (vaultIds.asKnown().getOrNull()?.size ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + environment == other.environment && + vaultIds == other.vaultIds && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(environment, vaultIds, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Body{}" + } + + /** The required hosting type and its configuration. */ + class Environment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonValue, + private val capabilityDirectories: JsonField>, + private val desktop: JsonField, + private val env: JsonField, + private val environmentTemplateId: JsonField, + private val files: JsonField>, + private val network: JsonField, + private val packages: JsonField, + private val plugins: JsonField>, + private val setupCommands: JsonField>, + private val skills: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("capability_directories") + @ExcludeMissing + capabilityDirectories: JsonField> = JsonMissing.of(), + @JsonProperty("desktop") @ExcludeMissing desktop: JsonField = JsonMissing.of(), + @JsonProperty("env") @ExcludeMissing env: JsonField = JsonMissing.of(), + @JsonProperty("environment_template_id") + @ExcludeMissing + environmentTemplateId: JsonField = JsonMissing.of(), + @JsonProperty("files") + @ExcludeMissing + files: JsonField> = JsonMissing.of(), + @JsonProperty("network") @ExcludeMissing network: JsonField = JsonMissing.of(), + @JsonProperty("packages") + @ExcludeMissing + packages: JsonField = JsonMissing.of(), + @JsonProperty("plugins") + @ExcludeMissing + plugins: JsonField> = JsonMissing.of(), + @JsonProperty("setup_commands") + @ExcludeMissing + setupCommands: JsonField> = JsonMissing.of(), + @JsonProperty("skills") + @ExcludeMissing + skills: JsonField> = JsonMissing.of(), + ) : this( + type, + capabilityDirectories, + desktop, + env, + environmentTemplateId, + files, + network, + packages, + plugins, + setupCommands, + skills, + mutableMapOf(), + ) + + /** + * The type of the object. Always `openai_hosted`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("openai_hosted") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Directories that contain capabilities exposed to the agent. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun capabilityDirectories(): Optional> = + capabilityDirectories.getOptional("capability_directories") + + /** + * Desktop provisioning. Omission or null inherits the template setting, or defaults to + * disabled. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun desktop(): Optional = desktop.getOptional("desktop") + + /** + * Environment variables made available to the agent. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun env(): Optional = env.getOptional("env") + + /** + * A reusable hosted template applied before inline configuration. Omitted fields inherit + * the template; network overrides cannot broaden its policy. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun environmentTemplateId(): Optional = + environmentTemplateId.getOptional("environment_template_id") + + /** + * Files available before the agent starts. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun files(): Optional> = files.getOptional("files") + + /** + * Network access policy for the environment. If omitted, the API version determines whether + * network access is enabled or disabled. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun network(): Optional = network.getOptional("network") + + /** + * Packages to install in the environment. Defaults to empty package lists. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun packages(): Optional = packages.getOptional("packages") + + /** + * Plugins provided as inline ZIP archives. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun plugins(): Optional> = plugins.getOptional("plugins") + + /** + * Ordered, confidential setup commands. Command bodies are never returned. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun setupCommands(): Optional> = + setupCommands.getOptional("setup_commands") + + /** + * Skills referenced by ID or provided as inline ZIP archives. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun skills(): Optional> = skills.getOptional("skills") + + /** + * Returns the raw JSON value of [capabilityDirectories]. + * + * Unlike [capabilityDirectories], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("capability_directories") + @ExcludeMissing + fun _capabilityDirectories(): JsonField> = capabilityDirectories + + /** + * Returns the raw JSON value of [desktop]. + * + * Unlike [desktop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("desktop") @ExcludeMissing fun _desktop(): JsonField = desktop + + /** + * Returns the raw JSON value of [env]. + * + * Unlike [env], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("env") @ExcludeMissing fun _env(): JsonField = env + + /** + * Returns the raw JSON value of [environmentTemplateId]. + * + * Unlike [environmentTemplateId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("environment_template_id") + @ExcludeMissing + fun _environmentTemplateId(): JsonField = environmentTemplateId + + /** + * Returns the raw JSON value of [files]. + * + * Unlike [files], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("files") + @ExcludeMissing + fun _files(): JsonField> = files + + /** + * Returns the raw JSON value of [network]. + * + * Unlike [network], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("network") @ExcludeMissing fun _network(): JsonField = network + + /** + * Returns the raw JSON value of [packages]. + * + * Unlike [packages], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("packages") @ExcludeMissing fun _packages(): JsonField = packages + + /** + * Returns the raw JSON value of [plugins]. + * + * Unlike [plugins], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("plugins") + @ExcludeMissing + fun _plugins(): JsonField> = plugins + + /** + * Returns the raw JSON value of [setupCommands]. + * + * Unlike [setupCommands], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("setup_commands") + @ExcludeMissing + fun _setupCommands(): JsonField> = setupCommands + + /** + * Returns the raw JSON value of [skills]. + * + * Unlike [skills], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("skills") + @ExcludeMissing + fun _skills(): JsonField> = skills + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Environment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Environment]. */ + class Builder internal constructor() { + + private var type: JsonValue = JsonValue.from("openai_hosted") + private var capabilityDirectories: JsonField>? = null + private var desktop: JsonField = JsonMissing.of() + private var env: JsonField = JsonMissing.of() + private var environmentTemplateId: JsonField = JsonMissing.of() + private var files: JsonField>? = null + private var network: JsonField = JsonMissing.of() + private var packages: JsonField = JsonMissing.of() + private var plugins: JsonField>? = null + private var setupCommands: JsonField>? = null + private var skills: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(environment: Environment) = apply { + type = environment.type + capabilityDirectories = environment.capabilityDirectories.map { it.toMutableList() } + desktop = environment.desktop + env = environment.env + environmentTemplateId = environment.environmentTemplateId + files = environment.files.map { it.toMutableList() } + network = environment.network + packages = environment.packages + plugins = environment.plugins.map { it.toMutableList() } + setupCommands = environment.setupCommands.map { it.toMutableList() } + skills = environment.skills.map { it.toMutableList() } + additionalProperties = environment.additionalProperties.toMutableMap() + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("openai_hosted") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * Directories that contain capabilities exposed to the agent. Defaults to an empty + * list. + */ + fun capabilityDirectories(capabilityDirectories: List?) = + capabilityDirectories(JsonField.ofNullable(capabilityDirectories)) + + /** + * Alias for calling [Builder.capabilityDirectories] with + * `capabilityDirectories.orElse(null)`. + */ + fun capabilityDirectories(capabilityDirectories: Optional>) = + capabilityDirectories(capabilityDirectories.getOrNull()) + + /** + * Sets [Builder.capabilityDirectories] to an arbitrary JSON value. + * + * You should usually call [Builder.capabilityDirectories] with a well-typed + * `List` value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun capabilityDirectories(capabilityDirectories: JsonField>) = apply { + this.capabilityDirectories = capabilityDirectories.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [capabilityDirectories]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addCapabilityDirectory(capabilityDirectory: String) = apply { + capabilityDirectories = + (capabilityDirectories ?: JsonField.of(mutableListOf())).also { + checkKnown("capabilityDirectories", it).add(capabilityDirectory) + } + } + + /** + * Desktop provisioning. Omission or null inherits the template setting, or defaults to + * disabled. + */ + fun desktop(desktop: Desktop?) = desktop(JsonField.ofNullable(desktop)) + + /** Alias for calling [Builder.desktop] with `desktop.orElse(null)`. */ + fun desktop(desktop: Optional) = desktop(desktop.getOrNull()) + + /** + * Sets [Builder.desktop] to an arbitrary JSON value. + * + * You should usually call [Builder.desktop] with a well-typed [Desktop] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun desktop(desktop: JsonField) = apply { this.desktop = desktop } + + /** Environment variables made available to the agent. */ + fun env(env: Env?) = env(JsonField.ofNullable(env)) + + /** Alias for calling [Builder.env] with `env.orElse(null)`. */ + fun env(env: Optional) = env(env.getOrNull()) + + /** + * Sets [Builder.env] to an arbitrary JSON value. + * + * You should usually call [Builder.env] with a well-typed [Env] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun env(env: JsonField) = apply { this.env = env } + + /** + * A reusable hosted template applied before inline configuration. Omitted fields + * inherit the template; network overrides cannot broaden its policy. + */ + fun environmentTemplateId(environmentTemplateId: String) = + environmentTemplateId(JsonField.of(environmentTemplateId)) + + /** + * Sets [Builder.environmentTemplateId] to an arbitrary JSON value. + * + * You should usually call [Builder.environmentTemplateId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun environmentTemplateId(environmentTemplateId: JsonField) = apply { + this.environmentTemplateId = environmentTemplateId + } + + /** Files available before the agent starts. Defaults to an empty list. */ + fun files(files: List?) = files(JsonField.ofNullable(files)) + + /** Alias for calling [Builder.files] with `files.orElse(null)`. */ + fun files(files: Optional>) = files(files.getOrNull()) + + /** + * Sets [Builder.files] to an arbitrary JSON value. + * + * You should usually call [Builder.files] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun files(files: JsonField>) = apply { + this.files = files.map { it.toMutableList() } + } + + /** + * Adds a single [HostedEnvironmentFileParam] to [files]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFile(file: HostedEnvironmentFileParam) = apply { + files = + (files ?: JsonField.of(mutableListOf())).also { + checkKnown("files", it).add(file) + } + } + + /** Alias for calling [addFile] with `HostedEnvironmentFileParam.ofFileId(fileId)`. */ + fun addFile(fileId: HostedEnvironmentFileParam.FileId) = + addFile(HostedEnvironmentFileParam.ofFileId(fileId)) + + /** Alias for calling [addFile] with `HostedEnvironmentFileParam.ofInline(inline)`. */ + fun addFile(inline: HostedEnvironmentFileParam.Inline) = + addFile(HostedEnvironmentFileParam.ofInline(inline)) + + /** + * Network access policy for the environment. If omitted, the API version determines + * whether network access is enabled or disabled. + */ + fun network(network: Network?) = network(JsonField.ofNullable(network)) + + /** Alias for calling [Builder.network] with `network.orElse(null)`. */ + fun network(network: Optional) = network(network.getOrNull()) + + /** + * Sets [Builder.network] to an arbitrary JSON value. + * + * You should usually call [Builder.network] with a well-typed [Network] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun network(network: JsonField) = apply { this.network = network } + + /** Packages to install in the environment. Defaults to empty package lists. */ + fun packages(packages: Packages?) = packages(JsonField.ofNullable(packages)) + + /** Alias for calling [Builder.packages] with `packages.orElse(null)`. */ + fun packages(packages: Optional) = packages(packages.getOrNull()) + + /** + * Sets [Builder.packages] to an arbitrary JSON value. + * + * You should usually call [Builder.packages] with a well-typed [Packages] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun packages(packages: JsonField) = apply { this.packages = packages } + + /** Plugins provided as inline ZIP archives. Defaults to an empty list. */ + fun plugins(plugins: List?) = plugins(JsonField.ofNullable(plugins)) + + /** Alias for calling [Builder.plugins] with `plugins.orElse(null)`. */ + fun plugins(plugins: Optional>) = plugins(plugins.getOrNull()) + + /** + * Sets [Builder.plugins] to an arbitrary JSON value. + * + * You should usually call [Builder.plugins] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun plugins(plugins: JsonField>) = apply { + this.plugins = plugins.map { it.toMutableList() } + } + + /** + * Adds a single [HostedPluginParam] to [plugins]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addPlugin(plugin: HostedPluginParam) = apply { + plugins = + (plugins ?: JsonField.of(mutableListOf())).also { + checkKnown("plugins", it).add(plugin) + } + } + + /** Ordered, confidential setup commands. Command bodies are never returned. */ + fun setupCommands(setupCommands: List?) = + setupCommands(JsonField.ofNullable(setupCommands)) + + /** Alias for calling [Builder.setupCommands] with `setupCommands.orElse(null)`. */ + fun setupCommands(setupCommands: Optional>) = + setupCommands(setupCommands.getOrNull()) + + /** + * Sets [Builder.setupCommands] to an arbitrary JSON value. + * + * You should usually call [Builder.setupCommands] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun setupCommands(setupCommands: JsonField>) = apply { + this.setupCommands = setupCommands.map { it.toMutableList() } + } + + /** + * Adds a single [SetupCommandParam] to [setupCommands]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSetupCommand(setupCommand: SetupCommandParam) = apply { + setupCommands = + (setupCommands ?: JsonField.of(mutableListOf())).also { + checkKnown("setupCommands", it).add(setupCommand) + } + } + + /** + * Skills referenced by ID or provided as inline ZIP archives. Defaults to an empty + * list. + */ + fun skills(skills: List?) = skills(JsonField.ofNullable(skills)) + + /** Alias for calling [Builder.skills] with `skills.orElse(null)`. */ + fun skills(skills: Optional>) = skills(skills.getOrNull()) + + /** + * Sets [Builder.skills] to an arbitrary JSON value. + * + * You should usually call [Builder.skills] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun skills(skills: JsonField>) = apply { + this.skills = skills.map { it.toMutableList() } + } + + /** + * Adds a single [HostedSkillParam] to [skills]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSkill(skill: HostedSkillParam) = apply { + skills = + (skills ?: JsonField.of(mutableListOf())).also { + checkKnown("skills", it).add(skill) + } + } + + /** + * Alias for calling [addSkill] with + * `HostedSkillParam.ofSkillReference(skillReference)`. + */ + fun addSkill(skillReference: HostedSkillParam.SkillReference) = + addSkill(HostedSkillParam.ofSkillReference(skillReference)) + + /** + * Alias for calling [addSkill] with the following: + * ```java + * HostedSkillParam.SkillReference.builder() + * .skillId(skillId) + * .build() + * ``` + */ + fun addSkillReferenceSkill(skillId: String) = + addSkill(HostedSkillParam.SkillReference.builder().skillId(skillId).build()) + + /** Alias for calling [addSkill] with `HostedSkillParam.ofInline(inline)`. */ + fun addSkill(inline: HostedSkillParam.Inline) = + addSkill(HostedSkillParam.ofInline(inline)) + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Environment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Environment = + Environment( + type, + (capabilityDirectories ?: JsonMissing.of()).map { it.toImmutable() }, + desktop, + env, + environmentTemplateId, + (files ?: JsonMissing.of()).map { it.toImmutable() }, + network, + packages, + (plugins ?: JsonMissing.of()).map { it.toImmutable() }, + (setupCommands ?: JsonMissing.of()).map { it.toImmutable() }, + (skills ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Environment = apply { + if (validated) { + return@apply + } + + _type().let { + if (it != JsonValue.from("openai_hosted")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + capabilityDirectories() + desktop().ifPresent { it.validate() } + env().ifPresent { it.validate() } + environmentTemplateId() + files().ifPresent { it.forEach { it.validate() } } + network().ifPresent { it.validate() } + packages().ifPresent { it.validate() } + plugins().ifPresent { it.forEach { it.validate() } } + setupCommands().ifPresent { it.forEach { it.validate() } } + skills().ifPresent { it.forEach { it.validate() } } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + type.let { if (it == JsonValue.from("openai_hosted")) 1 else 0 } + + (capabilityDirectories.asKnown().getOrNull()?.size ?: 0) + + (desktop.asKnown().getOrNull()?.validity() ?: 0) + + (env.asKnown().getOrNull()?.validity() ?: 0) + + (if (environmentTemplateId.asKnown().isPresent) 1 else 0) + + (files.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (network.asKnown().getOrNull()?.validity() ?: 0) + + (packages.asKnown().getOrNull()?.validity() ?: 0) + + (plugins.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (setupCommands.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (skills.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + /** + * Desktop provisioning. Omission or null inherits the template setting, or defaults to + * disabled. + */ + class Desktop + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val enabled: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("enabled") + @ExcludeMissing + enabled: JsonField = JsonMissing.of() + ) : this(enabled, mutableMapOf()) + + /** + * Whether to provision the desktop and its browser proxy. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun enabled(): Boolean = enabled.getRequired("enabled") + + /** + * Returns the raw JSON value of [enabled]. + * + * Unlike [enabled], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("enabled") @ExcludeMissing fun _enabled(): JsonField = enabled + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Desktop]. + * + * The following fields are required: + * ```java + * .enabled() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Desktop]. */ + class Builder internal constructor() { + + private var enabled: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(desktop: Desktop) = apply { + enabled = desktop.enabled + additionalProperties = desktop.additionalProperties.toMutableMap() + } + + /** Whether to provision the desktop and its browser proxy. */ + fun enabled(enabled: Boolean) = enabled(JsonField.of(enabled)) + + /** + * Sets [Builder.enabled] to an arbitrary JSON value. + * + * You should usually call [Builder.enabled] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun enabled(enabled: JsonField) = apply { this.enabled = enabled } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Desktop]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .enabled() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Desktop = + Desktop(checkRequired("enabled", enabled), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Desktop = apply { + if (validated) { + return@apply + } + + enabled() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (enabled.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Desktop && + enabled == other.enabled && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(enabled, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Desktop{enabled=$enabled, additionalProperties=$additionalProperties}" + } + + /** Environment variables made available to the agent. */ + class Env + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Env]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Env]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(env: Env) = apply { + additionalProperties = env.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + /** Adds a string-valued property. */ + fun putProperty(key: String, value: String) = apply { + putAdditionalProperty(key, JsonValue.from(value)) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Env]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Env = Env(additionalProperties.toImmutable()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Env = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Env && additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Env{}" + } + + /** + * Network access policy for the environment. If omitted, the API version determines whether + * network access is enabled or disabled. + */ + class Network + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val access: JsonField, + private val allowedDomains: JsonField>, + private val blockedDomains: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("access") + @ExcludeMissing + access: JsonField = JsonMissing.of(), + @JsonProperty("allowed_domains") + @ExcludeMissing + allowedDomains: JsonField> = JsonMissing.of(), + @JsonProperty("blocked_domains") + @ExcludeMissing + blockedDomains: JsonField> = JsonMissing.of(), + ) : this(access, allowedDomains, blockedDomains, mutableMapOf()) + + /** + * The environment's network access mode. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun access(): Access = access.getRequired("access") + + /** + * Domains the environment may access when network access is restricted. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun allowedDomains(): Optional> = + allowedDomains.getOptional("allowed_domains") + + /** + * Domains blocked for both executor and browser when access is restricted. A nonempty + * list requires `access: restricted` and cannot be combined with nonempty + * `allowed_domains`. Wildcard domains are not supported. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun blockedDomains(): Optional> = + blockedDomains.getOptional("blocked_domains") + + /** + * Returns the raw JSON value of [access]. + * + * Unlike [access], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("access") @ExcludeMissing fun _access(): JsonField = access + + /** + * Returns the raw JSON value of [allowedDomains]. + * + * Unlike [allowedDomains], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("allowed_domains") + @ExcludeMissing + fun _allowedDomains(): JsonField> = allowedDomains + + /** + * Returns the raw JSON value of [blockedDomains]. + * + * Unlike [blockedDomains], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("blocked_domains") + @ExcludeMissing + fun _blockedDomains(): JsonField> = blockedDomains + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Network]. + * + * The following fields are required: + * ```java + * .access() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Network]. */ + class Builder internal constructor() { + + private var access: JsonField? = null + private var allowedDomains: JsonField>? = null + private var blockedDomains: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(network: Network) = apply { + access = network.access + allowedDomains = network.allowedDomains.map { it.toMutableList() } + blockedDomains = network.blockedDomains.map { it.toMutableList() } + additionalProperties = network.additionalProperties.toMutableMap() + } + + /** The environment's network access mode. */ + fun access(access: Access) = access(JsonField.of(access)) + + /** + * Sets [Builder.access] to an arbitrary JSON value. + * + * You should usually call [Builder.access] with a well-typed [Access] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun access(access: JsonField) = apply { this.access = access } + + /** Domains the environment may access when network access is restricted. */ + fun allowedDomains(allowedDomains: List?) = + allowedDomains(JsonField.ofNullable(allowedDomains)) + + /** + * Alias for calling [Builder.allowedDomains] with `allowedDomains.orElse(null)`. + */ + fun allowedDomains(allowedDomains: Optional>) = + allowedDomains(allowedDomains.getOrNull()) + + /** + * Sets [Builder.allowedDomains] to an arbitrary JSON value. + * + * You should usually call [Builder.allowedDomains] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun allowedDomains(allowedDomains: JsonField>) = apply { + this.allowedDomains = allowedDomains.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [allowedDomains]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAllowedDomain(allowedDomain: String) = apply { + allowedDomains = + (allowedDomains ?: JsonField.of(mutableListOf())).also { + checkKnown("allowedDomains", it).add(allowedDomain) + } + } + + /** + * Domains blocked for both executor and browser when access is restricted. A + * nonempty list requires `access: restricted` and cannot be combined with nonempty + * `allowed_domains`. Wildcard domains are not supported. + */ + fun blockedDomains(blockedDomains: List?) = + blockedDomains(JsonField.ofNullable(blockedDomains)) + + /** + * Alias for calling [Builder.blockedDomains] with `blockedDomains.orElse(null)`. + */ + fun blockedDomains(blockedDomains: Optional>) = + blockedDomains(blockedDomains.getOrNull()) + + /** + * Sets [Builder.blockedDomains] to an arbitrary JSON value. + * + * You should usually call [Builder.blockedDomains] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun blockedDomains(blockedDomains: JsonField>) = apply { + this.blockedDomains = blockedDomains.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [blockedDomains]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addBlockedDomain(blockedDomain: String) = apply { + blockedDomains = + (blockedDomains ?: JsonField.of(mutableListOf())).also { + checkKnown("blockedDomains", it).add(blockedDomain) + } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Network]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .access() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Network = + Network( + checkRequired("access", access), + (allowedDomains ?: JsonMissing.of()).map { it.toImmutable() }, + (blockedDomains ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Network = apply { + if (validated) { + return@apply + } + + access().validate() + allowedDomains() + blockedDomains() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (access.asKnown().getOrNull()?.validity() ?: 0) + + (allowedDomains.asKnown().getOrNull()?.size ?: 0) + + (blockedDomains.asKnown().getOrNull()?.size ?: 0) + + /** The environment's network access mode. */ + class Access @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + /** Allows unrestricted network access. */ + @JvmField val ENABLED = of("enabled") + + /** Disables network access. */ + @JvmField val DISABLED = of("disabled") + + /** Applies the configured domain restrictions. */ + @JvmField val RESTRICTED = of("restricted") + + @JvmStatic fun of(value: String) = Access(JsonField.of(value)) + } + + /** An enum containing [Access]'s known values. */ + enum class Known { + /** Allows unrestricted network access. */ + ENABLED, + /** Disables network access. */ + DISABLED, + /** Applies the configured domain restrictions. */ + RESTRICTED, + } + + /** + * An enum containing [Access]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Access] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + /** Allows unrestricted network access. */ + ENABLED, + /** Disables network access. */ + DISABLED, + /** Applies the configured domain restrictions. */ + RESTRICTED, + /** + * An enum member indicating that [Access] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ENABLED -> Value.ENABLED + DISABLED -> Value.DISABLED + RESTRICTED -> Value.RESTRICTED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + ENABLED -> Known.ENABLED + DISABLED -> Known.DISABLED + RESTRICTED -> Known.RESTRICTED + else -> throw OpenAIInvalidDataException("Unknown Access: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Access = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Access && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Network && + access == other.access && + allowedDomains == other.allowedDomains && + blockedDomains == other.blockedDomains && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(access, allowedDomains, blockedDomains, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Network{access=$access, allowedDomains=$allowedDomains, blockedDomains=$blockedDomains, additionalProperties=$additionalProperties}" + } + + /** Packages to install in the environment. Defaults to empty package lists. */ + class Packages + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val npm: JsonField>, + private val python: JsonField>, + private val system: JsonField>, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("npm") + @ExcludeMissing + npm: JsonField> = JsonMissing.of(), + @JsonProperty("python") + @ExcludeMissing + python: JsonField> = JsonMissing.of(), + @JsonProperty("system") + @ExcludeMissing + system: JsonField> = JsonMissing.of(), + ) : this(npm, python, system, mutableMapOf()) + + /** + * npm packages to install globally. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun npm(): Optional> = npm.getOptional("npm") + + /** + * Python packages to install. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun python(): Optional> = python.getOptional("python") + + /** + * System packages to install. Defaults to an empty list. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun system(): Optional> = system.getOptional("system") + + /** + * Returns the raw JSON value of [npm]. + * + * Unlike [npm], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("npm") @ExcludeMissing fun _npm(): JsonField> = npm + + /** + * Returns the raw JSON value of [python]. + * + * Unlike [python], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("python") @ExcludeMissing fun _python(): JsonField> = python + + /** + * Returns the raw JSON value of [system]. + * + * Unlike [system], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("system") @ExcludeMissing fun _system(): JsonField> = system + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Packages]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Packages]. */ + class Builder internal constructor() { + + private var npm: JsonField>? = null + private var python: JsonField>? = null + private var system: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(packages: Packages) = apply { + npm = packages.npm.map { it.toMutableList() } + python = packages.python.map { it.toMutableList() } + system = packages.system.map { it.toMutableList() } + additionalProperties = packages.additionalProperties.toMutableMap() + } + + /** npm packages to install globally. Defaults to an empty list. */ + fun npm(npm: List?) = npm(JsonField.ofNullable(npm)) + + /** Alias for calling [Builder.npm] with `npm.orElse(null)`. */ + fun npm(npm: Optional>) = npm(npm.getOrNull()) + + /** + * Sets [Builder.npm] to an arbitrary JSON value. + * + * You should usually call [Builder.npm] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun npm(npm: JsonField>) = apply { + this.npm = npm.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [Builder.npm]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addNpm(npm: String) = apply { + this.npm = + (this.npm ?: JsonField.of(mutableListOf())).also { + checkKnown("npm", it).add(npm) + } + } + + /** Python packages to install. Defaults to an empty list. */ + fun python(python: List?) = python(JsonField.ofNullable(python)) + + /** Alias for calling [Builder.python] with `python.orElse(null)`. */ + fun python(python: Optional>) = python(python.getOrNull()) + + /** + * Sets [Builder.python] to an arbitrary JSON value. + * + * You should usually call [Builder.python] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun python(python: JsonField>) = apply { + this.python = python.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [Builder.python]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addPython(python: String) = apply { + this.python = + (this.python ?: JsonField.of(mutableListOf())).also { + checkKnown("python", it).add(python) + } + } + + /** System packages to install. Defaults to an empty list. */ + fun system(system: List?) = system(JsonField.ofNullable(system)) + + /** Alias for calling [Builder.system] with `system.orElse(null)`. */ + fun system(system: Optional>) = system(system.getOrNull()) + + /** + * Sets [Builder.system] to an arbitrary JSON value. + * + * You should usually call [Builder.system] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun system(system: JsonField>) = apply { + this.system = system.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [Builder.system]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSystem(system: String) = apply { + this.system = + (this.system ?: JsonField.of(mutableListOf())).also { + checkKnown("system", it).add(system) + } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Packages]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Packages = + Packages( + (npm ?: JsonMissing.of()).map { it.toImmutable() }, + (python ?: JsonMissing.of()).map { it.toImmutable() }, + (system ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Packages = apply { + if (validated) { + return@apply + } + + npm() + python() + system() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (npm.asKnown().getOrNull()?.size ?: 0) + + (python.asKnown().getOrNull()?.size ?: 0) + + (system.asKnown().getOrNull()?.size ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Packages && + npm == other.npm && + python == other.python && + system == other.system && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(npm, python, system, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Packages{npm=$npm, python=$python, system=$system, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Environment && + type == other.type && + capabilityDirectories == other.capabilityDirectories && + desktop == other.desktop && + env == other.env && + environmentTemplateId == other.environmentTemplateId && + files == other.files && + network == other.network && + packages == other.packages && + plugins == other.plugins && + setupCommands == other.setupCommands && + skills == other.skills && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + type, + capabilityDirectories, + desktop, + env, + environmentTemplateId, + files, + network, + packages, + plugins, + setupCommands, + skills, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Environment{}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EnvironmentCreateParams && + idempotencyKey == other.idempotencyKey && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(idempotencyKey, body, additionalHeaders, additionalQueryParams) + + override fun toString() = "EnvironmentCreateParams{}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentInfo.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentInfo.kt index 35e94163f..f74602c67 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentInfo.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentInfo.kt @@ -470,6 +470,9 @@ private constructor( @JvmField val PENDING = of("pending") + /** Provisioning succeeded and the environment is available for attachment or use. */ + @JvmField val READY = of("ready") + @JvmField val CONNECTED = of("connected") @JvmField val DISCONNECTED = of("disconnected") @@ -484,6 +487,8 @@ private constructor( /** An enum containing [Status]'s known values. */ enum class Known { PENDING, + /** Provisioning succeeded and the environment is available for attachment or use. */ + READY, CONNECTED, DISCONNECTED, EXPIRED, @@ -501,6 +506,8 @@ private constructor( */ enum class Value { PENDING, + /** Provisioning succeeded and the environment is available for attachment or use. */ + READY, CONNECTED, DISCONNECTED, EXPIRED, @@ -519,6 +526,7 @@ private constructor( fun value(): Value = when (this) { PENDING -> Value.PENDING + READY -> Value.READY CONNECTED -> Value.CONNECTED DISCONNECTED -> Value.DISCONNECTED EXPIRED -> Value.EXPIRED @@ -538,6 +546,7 @@ private constructor( fun known(): Known = when (this) { PENDING -> Known.PENDING + READY -> Known.READY CONNECTED -> Known.CONNECTED DISCONNECTED -> Known.DISCONNECTED EXPIRED -> Known.EXPIRED diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPage.kt new file mode 100644 index 000000000..6debe5ca9 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPage.kt @@ -0,0 +1,129 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.openai.core.AutoPager +import com.openai.core.Page +import com.openai.core.checkRequired +import com.openai.services.blocking.beta.agents.EnvironmentService +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** @see EnvironmentService.list */ +class EnvironmentListPage +private constructor( + private val service: EnvironmentService, + private val params: EnvironmentListParams, + private val response: EnvironmentListPageResponse, +) : Page { + + /** + * Delegates to [EnvironmentListPageResponse], but gracefully handles missing data. + * + * @see EnvironmentListPageResponse.data + */ + fun data(): List = + response._data().getOptional("data").getOrNull() ?: emptyList() + + /** + * Delegates to [EnvironmentListPageResponse], but gracefully handles missing data. + * + * @see EnvironmentListPageResponse.hasMore + */ + fun hasMore(): Optional = response._hasMore().getOptional("has_more") + + override fun items(): List = data() + + override fun hasNextPage(): Boolean = hasMore().orElse(true) && items().isNotEmpty() + + fun nextPageParams(): EnvironmentListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() + + override fun nextPage(): EnvironmentListPage = service.list(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) + + /** The parameters that were used to request this page. */ + fun params(): EnvironmentListParams = params + + /** The response that this page was parsed from. */ + fun response(): EnvironmentListPageResponse = response + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EnvironmentListPage]. + * + * The following fields are required: + * ```java + * .service() + * .params() + * .response() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EnvironmentListPage]. */ + class Builder internal constructor() { + + private var service: EnvironmentService? = null + private var params: EnvironmentListParams? = null + private var response: EnvironmentListPageResponse? = null + + @JvmSynthetic + internal fun from(environmentListPage: EnvironmentListPage) = apply { + service = environmentListPage.service + params = environmentListPage.params + response = environmentListPage.response + } + + fun service(service: EnvironmentService) = apply { this.service = service } + + /** The parameters that were used to request this page. */ + fun params(params: EnvironmentListParams) = apply { this.params = params } + + /** The response that this page was parsed from. */ + fun response(response: EnvironmentListPageResponse) = apply { this.response = response } + + /** + * Returns an immutable instance of [EnvironmentListPage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .service() + * .params() + * .response() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EnvironmentListPage = + EnvironmentListPage( + checkRequired("service", service), + checkRequired("params", params), + checkRequired("response", response), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EnvironmentListPage && + service == other.service && + params == other.params && + response == other.response + } + + override fun hashCode(): Int = Objects.hash(service, params, response) + + override fun toString() = + "EnvironmentListPage{service=$service, params=$params, response=$response}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageAsync.kt new file mode 100644 index 000000000..ae309e77e --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageAsync.kt @@ -0,0 +1,144 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.openai.core.AutoPagerAsync +import com.openai.core.PageAsync +import com.openai.core.checkRequired +import com.openai.services.async.beta.agents.EnvironmentServiceAsync +import java.util.Objects +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import kotlin.jvm.optionals.getOrNull + +/** @see EnvironmentServiceAsync.list */ +class EnvironmentListPageAsync +private constructor( + private val service: EnvironmentServiceAsync, + private val streamHandlerExecutor: Executor, + private val params: EnvironmentListParams, + private val response: EnvironmentListPageResponse, +) : PageAsync { + + /** + * Delegates to [EnvironmentListPageResponse], but gracefully handles missing data. + * + * @see EnvironmentListPageResponse.data + */ + fun data(): List = + response._data().getOptional("data").getOrNull() ?: emptyList() + + /** + * Delegates to [EnvironmentListPageResponse], but gracefully handles missing data. + * + * @see EnvironmentListPageResponse.hasMore + */ + fun hasMore(): Optional = response._hasMore().getOptional("has_more") + + override fun items(): List = data() + + override fun hasNextPage(): Boolean = hasMore().orElse(true) && items().isNotEmpty() + + fun nextPageParams(): EnvironmentListParams = + params.toBuilder().after(items().last()._id().getOptional("id")).build() + + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) + + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) + + /** The parameters that were used to request this page. */ + fun params(): EnvironmentListParams = params + + /** The response that this page was parsed from. */ + fun response(): EnvironmentListPageResponse = response + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EnvironmentListPageAsync]. + * + * The following fields are required: + * ```java + * .service() + * .streamHandlerExecutor() + * .params() + * .response() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EnvironmentListPageAsync]. */ + class Builder internal constructor() { + + private var service: EnvironmentServiceAsync? = null + private var streamHandlerExecutor: Executor? = null + private var params: EnvironmentListParams? = null + private var response: EnvironmentListPageResponse? = null + + @JvmSynthetic + internal fun from(environmentListPageAsync: EnvironmentListPageAsync) = apply { + service = environmentListPageAsync.service + streamHandlerExecutor = environmentListPageAsync.streamHandlerExecutor + params = environmentListPageAsync.params + response = environmentListPageAsync.response + } + + fun service(service: EnvironmentServiceAsync) = apply { this.service = service } + + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + + /** The parameters that were used to request this page. */ + fun params(params: EnvironmentListParams) = apply { this.params = params } + + /** The response that this page was parsed from. */ + fun response(response: EnvironmentListPageResponse) = apply { this.response = response } + + /** + * Returns an immutable instance of [EnvironmentListPageAsync]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .service() + * .streamHandlerExecutor() + * .params() + * .response() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EnvironmentListPageAsync = + EnvironmentListPageAsync( + checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), + checkRequired("params", params), + checkRequired("response", response), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EnvironmentListPageAsync && + service == other.service && + streamHandlerExecutor == other.streamHandlerExecutor && + params == other.params && + response == other.response + } + + override fun hashCode(): Int = Objects.hash(service, streamHandlerExecutor, params, response) + + override fun toString() = + "EnvironmentListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageResponse.kt new file mode 100644 index 000000000..25a37a019 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageResponse.kt @@ -0,0 +1,364 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkKnown +import com.openai.core.checkRequired +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A page of Agents API resources, with IDs for retrieving additional pages. */ +class EnvironmentListPageResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val data: JsonField>, + private val firstId: JsonField, + private val hasMore: JsonField, + private val lastId: JsonField, + private val object_: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("data") + @ExcludeMissing + data: JsonField> = JsonMissing.of(), + @JsonProperty("first_id") @ExcludeMissing firstId: JsonField = JsonMissing.of(), + @JsonProperty("has_more") @ExcludeMissing hasMore: JsonField = JsonMissing.of(), + @JsonProperty("last_id") @ExcludeMissing lastId: JsonField = JsonMissing.of(), + @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), + ) : this(data, firstId, hasMore, lastId, object_, mutableMapOf()) + + /** + * The resources returned in this page, in the requested sort order. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): List = data.getRequired("data") + + /** + * The ID of the first resource in `data`, or `null` if the page is empty. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun firstId(): Optional = firstId.getOptional("first_id") + + /** + * Whether there are more resources to retrieve after this page. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun hasMore(): Boolean = hasMore.getRequired("has_more") + + /** + * The ID of the last resource in `data`, or `null` if the page is empty. Pass this as `after` + * with the same order and filters. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun lastId(): Optional = lastId.getOptional("last_id") + + /** + * The object type, which is always `list`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("list") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_ + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField> = data + + /** + * Returns the raw JSON value of [firstId]. + * + * Unlike [firstId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("first_id") @ExcludeMissing fun _firstId(): JsonField = firstId + + /** + * Returns the raw JSON value of [hasMore]. + * + * Unlike [hasMore], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("has_more") @ExcludeMissing fun _hasMore(): JsonField = hasMore + + /** + * Returns the raw JSON value of [lastId]. + * + * Unlike [lastId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("last_id") @ExcludeMissing fun _lastId(): JsonField = lastId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EnvironmentListPageResponse]. + * + * The following fields are required: + * ```java + * .data() + * .firstId() + * .hasMore() + * .lastId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EnvironmentListPageResponse]. */ + class Builder internal constructor() { + + private var data: JsonField>? = null + private var firstId: JsonField? = null + private var hasMore: JsonField? = null + private var lastId: JsonField? = null + private var object_: JsonValue = JsonValue.from("list") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(environmentListPageResponse: EnvironmentListPageResponse) = apply { + data = environmentListPageResponse.data.map { it.toMutableList() } + firstId = environmentListPageResponse.firstId + hasMore = environmentListPageResponse.hasMore + lastId = environmentListPageResponse.lastId + object_ = environmentListPageResponse.object_ + additionalProperties = environmentListPageResponse.additionalProperties.toMutableMap() + } + + /** The resources returned in this page, in the requested sort order. */ + fun data(data: List) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun data(data: JsonField>) = apply { + this.data = data.map { it.toMutableList() } + } + + /** + * Adds a single [EnvironmentInfo] to [Builder.data]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addData(data: EnvironmentInfo) = apply { + this.data = + (this.data ?: JsonField.of(mutableListOf())).also { + checkKnown("data", it).add(data) + } + } + + /** The ID of the first resource in `data`, or `null` if the page is empty. */ + fun firstId(firstId: String?) = firstId(JsonField.ofNullable(firstId)) + + /** Alias for calling [Builder.firstId] with `firstId.orElse(null)`. */ + fun firstId(firstId: Optional) = firstId(firstId.getOrNull()) + + /** + * Sets [Builder.firstId] to an arbitrary JSON value. + * + * You should usually call [Builder.firstId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun firstId(firstId: JsonField) = apply { this.firstId = firstId } + + /** Whether there are more resources to retrieve after this page. */ + fun hasMore(hasMore: Boolean) = hasMore(JsonField.of(hasMore)) + + /** + * Sets [Builder.hasMore] to an arbitrary JSON value. + * + * You should usually call [Builder.hasMore] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun hasMore(hasMore: JsonField) = apply { this.hasMore = hasMore } + + /** + * The ID of the last resource in `data`, or `null` if the page is empty. Pass this as + * `after` with the same order and filters. + */ + fun lastId(lastId: String?) = lastId(JsonField.ofNullable(lastId)) + + /** Alias for calling [Builder.lastId] with `lastId.orElse(null)`. */ + fun lastId(lastId: Optional) = lastId(lastId.getOrNull()) + + /** + * Sets [Builder.lastId] to an arbitrary JSON value. + * + * You should usually call [Builder.lastId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun lastId(lastId: JsonField) = apply { this.lastId = lastId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("list") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun object_(object_: JsonValue) = apply { this.object_ = object_ } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [EnvironmentListPageResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .firstId() + * .hasMore() + * .lastId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EnvironmentListPageResponse = + EnvironmentListPageResponse( + checkRequired("data", data).map { it.toImmutable() }, + checkRequired("firstId", firstId), + checkRequired("hasMore", hasMore), + checkRequired("lastId", lastId), + object_, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): EnvironmentListPageResponse = apply { + if (validated) { + return@apply + } + + data().forEach { it.validate() } + firstId() + hasMore() + lastId() + _object_().let { + if (it != JsonValue.from("list")) { + throw OpenAIInvalidDataException("'object_' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (data.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (firstId.asKnown().isPresent) 1 else 0) + + (if (hasMore.asKnown().isPresent) 1 else 0) + + (if (lastId.asKnown().isPresent) 1 else 0) + + object_.let { if (it == JsonValue.from("list")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EnvironmentListPageResponse && + data == other.data && + firstId == other.firstId && + hasMore == other.hasMore && + lastId == other.lastId && + object_ == other.object_ && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(data, firstId, hasMore, lastId, object_, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EnvironmentListPageResponse{data=$data, firstId=$firstId, hasMore=$hasMore, lastId=$lastId, object_=$object_, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListParams.kt new file mode 100644 index 000000000..ef1817adb --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/agents/environments/EnvironmentListParams.kt @@ -0,0 +1,525 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.fasterxml.jackson.annotation.JsonCreator +import com.openai.core.Enum +import com.openai.core.JsonField +import com.openai.core.Params +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import com.openai.errors.OpenAIInvalidDataException +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Lists OpenAI-hosted environments owned by the authenticated principal. Requires access to the + * prewarming beta. + */ +class EnvironmentListParams +private constructor( + private val after: String?, + private val limit: Long?, + private val order: Order?, + private val type: Type?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Return environments after this environment ID in the selected order. */ + fun after(): Optional = Optional.ofNullable(after) + + /** The maximum number of environments to return, between 1 and 100. Defaults to 20. */ + fun limit(): Optional = Optional.ofNullable(limit) + + /** The order in which environments are returned. Defaults to `desc`. */ + fun order(): Optional = Optional.ofNullable(order) + + /** The hosting type to list. Defaults to `openai_hosted`. */ + fun type(): Optional = Optional.ofNullable(type) + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): EnvironmentListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [EnvironmentListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EnvironmentListParams]. */ + class Builder internal constructor() { + + private var after: String? = null + private var limit: Long? = null + private var order: Order? = null + private var type: Type? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(environmentListParams: EnvironmentListParams) = apply { + after = environmentListParams.after + limit = environmentListParams.limit + order = environmentListParams.order + type = environmentListParams.type + additionalHeaders = environmentListParams.additionalHeaders.toBuilder() + additionalQueryParams = environmentListParams.additionalQueryParams.toBuilder() + } + + /** Return environments after this environment ID in the selected order. */ + fun after(after: String?) = apply { this.after = after } + + /** Alias for calling [Builder.after] with `after.orElse(null)`. */ + fun after(after: Optional) = after(after.getOrNull()) + + /** The maximum number of environments to return, between 1 and 100. Defaults to 20. */ + fun limit(limit: Long?) = apply { this.limit = limit } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** The order in which environments are returned. Defaults to `desc`. */ + fun order(order: Order?) = apply { this.order = order } + + /** Alias for calling [Builder.order] with `order.orElse(null)`. */ + fun order(order: Optional) = order(order.getOrNull()) + + /** The hosting type to list. Defaults to `openai_hosted`. */ + fun type(type: Type?) = apply { this.type = type } + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [EnvironmentListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): EnvironmentListParams = + EnvironmentListParams( + after, + limit, + order, + type, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + after?.let { put("after", it) } + limit?.let { put("limit", it.toString()) } + order?.let { put("order", it.toString()) } + type?.let { put("type", it.toString()) } + putAll(additionalQueryParams) + } + .build() + + /** The order in which environments are returned. Defaults to `desc`. */ + class Order @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + /** Returns resources in ascending order. */ + @JvmField val ASC = of("asc") + + /** Returns resources in descending order. */ + @JvmField val DESC = of("desc") + + @JvmStatic fun of(value: String) = Order(JsonField.of(value)) + } + + /** An enum containing [Order]'s known values. */ + enum class Known { + /** Returns resources in ascending order. */ + ASC, + /** Returns resources in descending order. */ + DESC, + } + + /** + * An enum containing [Order]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Order] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + /** Returns resources in ascending order. */ + ASC, + /** Returns resources in descending order. */ + DESC, + /** An enum member indicating that [Order] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ASC -> Value.ASC + DESC -> Value.DESC + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ASC -> Known.ASC + DESC -> Known.DESC + else -> throw OpenAIInvalidDataException("Unknown Order: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Order = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Order && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The hosting type to list. Defaults to `openai_hosted`. */ + class Type @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val OPENAI_HOSTED = of("openai_hosted") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + OPENAI_HOSTED + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + OPENAI_HOSTED, + /** An enum member indicating that [Type] was instantiated with an unknown value. */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + OPENAI_HOSTED -> Value.OPENAI_HOSTED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + OPENAI_HOSTED -> Known.OPENAI_HOSTED + else -> throw OpenAIInvalidDataException("Unknown Type: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EnvironmentListParams && + after == other.after && + limit == other.limit && + order == other.order && + type == other.type && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(after, limit, order, type, additionalHeaders, additionalQueryParams) + + override fun toString() = + "EnvironmentListParams{after=$after, limit=$limit, order=$order, type=$type, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/AgentEnvironmentFailedWebhookEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/AgentEnvironmentFailedWebhookEvent.kt new file mode 100644 index 000000000..81670c0d9 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/AgentEnvironmentFailedWebhookEvent.kt @@ -0,0 +1,507 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** + * Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to a + * session. + */ +class AgentEnvironmentFailedWebhookEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val data: JsonField, + private val object_: JsonValue, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(id, createdAt, data, object_, type, mutableMapOf()) + + /** + * The unique ID of the event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The Unix timestamp, in seconds, when the event was created. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun createdAt(): Long = createdAt.getRequired("created_at") + + /** + * Identifies the environment whose lifecycle changed. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * The object type. Always `event`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("event") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_ + + /** + * The event type. Always `agent.environment.failed`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("agent.environment.failed") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [AgentEnvironmentFailedWebhookEvent]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AgentEnvironmentFailedWebhookEvent]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var data: JsonField? = null + private var object_: JsonValue = JsonValue.from("event") + private var type: JsonValue = JsonValue.from("agent.environment.failed") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agentEnvironmentFailedWebhookEvent: AgentEnvironmentFailedWebhookEvent) = + apply { + id = agentEnvironmentFailedWebhookEvent.id + createdAt = agentEnvironmentFailedWebhookEvent.createdAt + data = agentEnvironmentFailedWebhookEvent.data + object_ = agentEnvironmentFailedWebhookEvent.object_ + type = agentEnvironmentFailedWebhookEvent.type + additionalProperties = + agentEnvironmentFailedWebhookEvent.additionalProperties.toMutableMap() + } + + /** The unique ID of the event. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The Unix timestamp, in seconds, when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** Identifies the environment whose lifecycle changed. */ + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("event") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun object_(object_: JsonValue) = apply { this.object_ = object_ } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("agent.environment.failed") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AgentEnvironmentFailedWebhookEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AgentEnvironmentFailedWebhookEvent = + AgentEnvironmentFailedWebhookEvent( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("data", data), + object_, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): AgentEnvironmentFailedWebhookEvent = apply { + if (validated) { + return@apply + } + + id() + createdAt() + data().validate() + _object_().let { + if (it != JsonValue.from("event")) { + throw OpenAIInvalidDataException("'object_' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("agent.environment.failed")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + object_.let { if (it == JsonValue.from("event")) 1 else 0 } + + type.let { if (it == JsonValue.from("agent.environment.failed")) 1 else 0 } + + /** Identifies the environment whose lifecycle changed. */ + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of() + ) : this(id, mutableMapOf()) + + /** + * The ID of the environment. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + id = data.id + additionalProperties = data.additionalProperties.toMutableMap() + } + + /** The ID of the environment. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = Data(checkRequired("id", id), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Data = apply { + if (validated) { + return@apply + } + + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{id=$id, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AgentEnvironmentFailedWebhookEvent && + id == other.id && + createdAt == other.createdAt && + data == other.data && + object_ == other.object_ && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, createdAt, data, object_, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AgentEnvironmentFailedWebhookEvent{id=$id, createdAt=$createdAt, data=$data, object_=$object_, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/AgentEnvironmentReadyWebhookEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/AgentEnvironmentReadyWebhookEvent.kt new file mode 100644 index 000000000..8202d6772 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/AgentEnvironmentReadyWebhookEvent.kt @@ -0,0 +1,507 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** + * Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a + * session. + */ +class AgentEnvironmentReadyWebhookEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val data: JsonField, + private val object_: JsonValue, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(id, createdAt, data, object_, type, mutableMapOf()) + + /** + * The unique ID of the event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The Unix timestamp, in seconds, when the event was created. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun createdAt(): Long = createdAt.getRequired("created_at") + + /** + * Identifies the environment whose lifecycle changed. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * The object type. Always `event`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("event") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_ + + /** + * The event type. Always `agent.environment.ready`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("agent.environment.ready") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [AgentEnvironmentReadyWebhookEvent]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AgentEnvironmentReadyWebhookEvent]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var data: JsonField? = null + private var object_: JsonValue = JsonValue.from("event") + private var type: JsonValue = JsonValue.from("agent.environment.ready") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agentEnvironmentReadyWebhookEvent: AgentEnvironmentReadyWebhookEvent) = + apply { + id = agentEnvironmentReadyWebhookEvent.id + createdAt = agentEnvironmentReadyWebhookEvent.createdAt + data = agentEnvironmentReadyWebhookEvent.data + object_ = agentEnvironmentReadyWebhookEvent.object_ + type = agentEnvironmentReadyWebhookEvent.type + additionalProperties = + agentEnvironmentReadyWebhookEvent.additionalProperties.toMutableMap() + } + + /** The unique ID of the event. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The Unix timestamp, in seconds, when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + /** Identifies the environment whose lifecycle changed. */ + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("event") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun object_(object_: JsonValue) = apply { this.object_ = object_ } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("agent.environment.ready") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AgentEnvironmentReadyWebhookEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AgentEnvironmentReadyWebhookEvent = + AgentEnvironmentReadyWebhookEvent( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("data", data), + object_, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): AgentEnvironmentReadyWebhookEvent = apply { + if (validated) { + return@apply + } + + id() + createdAt() + data().validate() + _object_().let { + if (it != JsonValue.from("event")) { + throw OpenAIInvalidDataException("'object_' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("agent.environment.ready")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + object_.let { if (it == JsonValue.from("event")) 1 else 0 } + + type.let { if (it == JsonValue.from("agent.environment.ready")) 1 else 0 } + + /** Identifies the environment whose lifecycle changed. */ + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of() + ) : this(id, mutableMapOf()) + + /** + * The ID of the environment. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + id = data.id + additionalProperties = data.additionalProperties.toMutableMap() + } + + /** The ID of the environment. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = Data(checkRequired("id", id), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Data = apply { + if (validated) { + return@apply + } + + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{id=$id, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AgentEnvironmentReadyWebhookEvent && + id == other.id && + createdAt == other.createdAt && + data == other.data && + object_ == other.object_ && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, createdAt, data, object_, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AgentEnvironmentReadyWebhookEvent{id=$id, createdAt=$createdAt, data=$data, object_=$object_, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt index fef653edb..667d78c4b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt @@ -18,11 +18,16 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** Sent when an agent session requires an action. Retrieve the session for action details. */ +/** + * Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to a + * session. + */ @JsonDeserialize(using = UnwrapWebhookEvent.Deserializer::class) @JsonSerialize(using = UnwrapWebhookEvent.Serializer::class) class UnwrapWebhookEvent private constructor( + private val agentEnvironmentFailed: AgentEnvironmentFailedWebhookEvent? = null, + private val agentEnvironmentReady: AgentEnvironmentReadyWebhookEvent? = null, private val agentSessionActionRequired: AgentSessionActionRequiredWebhookEvent? = null, private val agentSessionCreated: AgentSessionCreatedWebhookEvent? = null, private val agentSessionFailed: AgentSessionFailedWebhookEvent? = null, @@ -52,6 +57,20 @@ private constructor( private val _json: JsonValue? = null, ) { + /** + * Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to a + * session. + */ + fun agentEnvironmentFailed(): Optional = + Optional.ofNullable(agentEnvironmentFailed) + + /** + * Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a + * session. + */ + fun agentEnvironmentReady(): Optional = + Optional.ofNullable(agentEnvironmentReady) + /** Sent when an agent session requires an action. Retrieve the session for action details. */ fun agentSessionActionRequired(): Optional = Optional.ofNullable(agentSessionActionRequired) @@ -165,6 +184,10 @@ private constructor( fun safetyWarningIssued(): Optional = Optional.ofNullable(safetyWarningIssued) + fun isAgentEnvironmentFailed(): Boolean = agentEnvironmentFailed != null + + fun isAgentEnvironmentReady(): Boolean = agentEnvironmentReady != null + fun isAgentSessionActionRequired(): Boolean = agentSessionActionRequired != null fun isAgentSessionCreated(): Boolean = agentSessionCreated != null @@ -217,6 +240,20 @@ private constructor( fun isSafetyWarningIssued(): Boolean = safetyWarningIssued != null + /** + * Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to a + * session. + */ + fun asAgentEnvironmentFailed(): AgentEnvironmentFailedWebhookEvent = + agentEnvironmentFailed.getOrThrow("agentEnvironmentFailed") + + /** + * Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a + * session. + */ + fun asAgentEnvironmentReady(): AgentEnvironmentReadyWebhookEvent = + agentEnvironmentReady.getOrThrow("agentEnvironmentReady") + /** Sent when an agent session requires an action. Retrieve the session for action details. */ fun asAgentSessionActionRequired(): AgentSessionActionRequiredWebhookEvent = agentSessionActionRequired.getOrThrow("agentSessionActionRequired") @@ -344,8 +381,8 @@ private constructor( * * Optional result = unwrapWebhookEvent.accept(new UnwrapWebhookEvent.Visitor>() { * @Override - * public Optional visitAgentSessionActionRequired(AgentSessionActionRequiredWebhookEvent agentSessionActionRequired) { - * return Optional.of(agentSessionActionRequired.toString()); + * public Optional visitAgentEnvironmentFailed(AgentEnvironmentFailedWebhookEvent agentEnvironmentFailed) { + * return Optional.of(agentEnvironmentFailed.toString()); * } * * // ... @@ -363,6 +400,10 @@ private constructor( */ fun accept(visitor: Visitor): T = when { + agentEnvironmentFailed != null -> + visitor.visitAgentEnvironmentFailed(agentEnvironmentFailed) + agentEnvironmentReady != null -> + visitor.visitAgentEnvironmentReady(agentEnvironmentReady) agentSessionActionRequired != null -> visitor.visitAgentSessionActionRequired(agentSessionActionRequired) agentSessionCreated != null -> visitor.visitAgentSessionCreated(agentSessionCreated) @@ -416,6 +457,18 @@ private constructor( accept( object : Visitor { + override fun visitAgentEnvironmentFailed( + agentEnvironmentFailed: AgentEnvironmentFailedWebhookEvent + ) { + agentEnvironmentFailed.validate() + } + + override fun visitAgentEnvironmentReady( + agentEnvironmentReady: AgentEnvironmentReadyWebhookEvent + ) { + agentEnvironmentReady.validate() + } + override fun visitAgentSessionActionRequired( agentSessionActionRequired: AgentSessionActionRequiredWebhookEvent ) { @@ -573,6 +626,14 @@ private constructor( internal fun validity(): Int = accept( object : Visitor { + override fun visitAgentEnvironmentFailed( + agentEnvironmentFailed: AgentEnvironmentFailedWebhookEvent + ) = agentEnvironmentFailed.validity() + + override fun visitAgentEnvironmentReady( + agentEnvironmentReady: AgentEnvironmentReadyWebhookEvent + ) = agentEnvironmentReady.validity() + override fun visitAgentSessionActionRequired( agentSessionActionRequired: AgentSessionActionRequiredWebhookEvent ) = agentSessionActionRequired.validity() @@ -677,6 +738,8 @@ private constructor( } return other is UnwrapWebhookEvent && + agentEnvironmentFailed == other.agentEnvironmentFailed && + agentEnvironmentReady == other.agentEnvironmentReady && agentSessionActionRequired == other.agentSessionActionRequired && agentSessionCreated == other.agentSessionCreated && agentSessionFailed == other.agentSessionFailed && @@ -707,6 +770,8 @@ private constructor( override fun hashCode(): Int = Objects.hash( + agentEnvironmentFailed, + agentEnvironmentReady, agentSessionActionRequired, agentSessionCreated, agentSessionFailed, @@ -737,6 +802,10 @@ private constructor( override fun toString(): String = when { + agentEnvironmentFailed != null -> + "UnwrapWebhookEvent{agentEnvironmentFailed=$agentEnvironmentFailed}" + agentEnvironmentReady != null -> + "UnwrapWebhookEvent{agentEnvironmentReady=$agentEnvironmentReady}" agentSessionActionRequired != null -> "UnwrapWebhookEvent{agentSessionActionRequired=$agentSessionActionRequired}" agentSessionCreated != null -> @@ -783,6 +852,22 @@ private constructor( companion object { + /** + * Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to + * a session. + */ + @JvmStatic + fun ofAgentEnvironmentFailed(agentEnvironmentFailed: AgentEnvironmentFailedWebhookEvent) = + UnwrapWebhookEvent(agentEnvironmentFailed = agentEnvironmentFailed) + + /** + * Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a + * session. + */ + @JvmStatic + fun ofAgentEnvironmentReady(agentEnvironmentReady: AgentEnvironmentReadyWebhookEvent) = + UnwrapWebhookEvent(agentEnvironmentReady = agentEnvironmentReady) + /** * Sent when an agent session requires an action. Retrieve the session for action details. */ @@ -939,6 +1024,22 @@ private constructor( */ interface Visitor { + /** + * Sent when setup fails for a prewarmed OpenAI-hosted environment before it is attached to + * a session. + */ + fun visitAgentEnvironmentFailed( + agentEnvironmentFailed: AgentEnvironmentFailedWebhookEvent + ): T = unknown(JsonValue.from(agentEnvironmentFailed)) + + /** + * Sent when a prewarmed OpenAI-hosted environment finishes setup before being attached to a + * session. + */ + fun visitAgentEnvironmentReady( + agentEnvironmentReady: AgentEnvironmentReadyWebhookEvent + ): T = unknown(JsonValue.from(agentEnvironmentReady)) + /** * Sent when an agent session requires an action. Retrieve the session for action details. */ @@ -1070,6 +1171,19 @@ private constructor( val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() when (type) { + "agent.environment.failed" -> { + return tryDeserialize( + node, + jacksonTypeRef(), + ) + ?.let { UnwrapWebhookEvent(agentEnvironmentFailed = it, _json = json) } + ?: UnwrapWebhookEvent(_json = json) + } + "agent.environment.ready" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { UnwrapWebhookEvent(agentEnvironmentReady = it, _json = json) } + ?: UnwrapWebhookEvent(_json = json) + } "agent.session.action_required" -> { return tryDeserialize( node, @@ -1229,6 +1343,10 @@ private constructor( provider: SerializerProvider, ) { when { + value.agentEnvironmentFailed != null -> + generator.writeObject(value.agentEnvironmentFailed) + value.agentEnvironmentReady != null -> + generator.writeObject(value.agentEnvironmentReady) value.agentSessionActionRequired != null -> generator.writeObject(value.agentSessionActionRequired) value.agentSessionCreated != null -> diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookCreateParams.kt index 1a84e4ffa..30c7cacc9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookCreateParams.kt @@ -625,6 +625,10 @@ private constructor( @JvmField val VIDEO_FAILED = of("video.failed") + @JvmField val AGENT_ENVIRONMENT_READY = of("agent.environment.ready") + + @JvmField val AGENT_ENVIRONMENT_FAILED = of("agent.environment.failed") + @JvmField val AGENT_SESSION_CREATED = of("agent.session.created") @JvmField val AGENT_SESSION_ACTION_REQUIRED = of("agent.session.action_required") @@ -659,6 +663,8 @@ private constructor( REALTIME_CALL_INCOMING, VIDEO_COMPLETED, VIDEO_FAILED, + AGENT_ENVIRONMENT_READY, + AGENT_ENVIRONMENT_FAILED, AGENT_SESSION_CREATED, AGENT_SESSION_ACTION_REQUIRED, AGENT_SESSION_IN_PROGRESS, @@ -694,6 +700,8 @@ private constructor( REALTIME_CALL_INCOMING, VIDEO_COMPLETED, VIDEO_FAILED, + AGENT_ENVIRONMENT_READY, + AGENT_ENVIRONMENT_FAILED, AGENT_SESSION_CREATED, AGENT_SESSION_ACTION_REQUIRED, AGENT_SESSION_IN_PROGRESS, @@ -732,6 +740,8 @@ private constructor( REALTIME_CALL_INCOMING -> Value.REALTIME_CALL_INCOMING VIDEO_COMPLETED -> Value.VIDEO_COMPLETED VIDEO_FAILED -> Value.VIDEO_FAILED + AGENT_ENVIRONMENT_READY -> Value.AGENT_ENVIRONMENT_READY + AGENT_ENVIRONMENT_FAILED -> Value.AGENT_ENVIRONMENT_FAILED AGENT_SESSION_CREATED -> Value.AGENT_SESSION_CREATED AGENT_SESSION_ACTION_REQUIRED -> Value.AGENT_SESSION_ACTION_REQUIRED AGENT_SESSION_IN_PROGRESS -> Value.AGENT_SESSION_IN_PROGRESS @@ -769,6 +779,8 @@ private constructor( REALTIME_CALL_INCOMING -> Known.REALTIME_CALL_INCOMING VIDEO_COMPLETED -> Known.VIDEO_COMPLETED VIDEO_FAILED -> Known.VIDEO_FAILED + AGENT_ENVIRONMENT_READY -> Known.AGENT_ENVIRONMENT_READY + AGENT_ENVIRONMENT_FAILED -> Known.AGENT_ENVIRONMENT_FAILED AGENT_SESSION_CREATED -> Known.AGENT_SESSION_CREATED AGENT_SESSION_ACTION_REQUIRED -> Known.AGENT_SESSION_ACTION_REQUIRED AGENT_SESSION_IN_PROGRESS -> Known.AGENT_SESSION_IN_PROGRESS diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookTestParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookTestParams.kt index 291ab7503..82e157174 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookTestParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookTestParams.kt @@ -484,6 +484,10 @@ private constructor( @JvmField val VIDEO_FAILED = of("video.failed") + @JvmField val AGENT_ENVIRONMENT_READY = of("agent.environment.ready") + + @JvmField val AGENT_ENVIRONMENT_FAILED = of("agent.environment.failed") + @JvmField val AGENT_SESSION_CREATED = of("agent.session.created") @JvmField val AGENT_SESSION_ACTION_REQUIRED = of("agent.session.action_required") @@ -518,6 +522,8 @@ private constructor( REALTIME_CALL_INCOMING, VIDEO_COMPLETED, VIDEO_FAILED, + AGENT_ENVIRONMENT_READY, + AGENT_ENVIRONMENT_FAILED, AGENT_SESSION_CREATED, AGENT_SESSION_ACTION_REQUIRED, AGENT_SESSION_IN_PROGRESS, @@ -553,6 +559,8 @@ private constructor( REALTIME_CALL_INCOMING, VIDEO_COMPLETED, VIDEO_FAILED, + AGENT_ENVIRONMENT_READY, + AGENT_ENVIRONMENT_FAILED, AGENT_SESSION_CREATED, AGENT_SESSION_ACTION_REQUIRED, AGENT_SESSION_IN_PROGRESS, @@ -591,6 +599,8 @@ private constructor( REALTIME_CALL_INCOMING -> Value.REALTIME_CALL_INCOMING VIDEO_COMPLETED -> Value.VIDEO_COMPLETED VIDEO_FAILED -> Value.VIDEO_FAILED + AGENT_ENVIRONMENT_READY -> Value.AGENT_ENVIRONMENT_READY + AGENT_ENVIRONMENT_FAILED -> Value.AGENT_ENVIRONMENT_FAILED AGENT_SESSION_CREATED -> Value.AGENT_SESSION_CREATED AGENT_SESSION_ACTION_REQUIRED -> Value.AGENT_SESSION_ACTION_REQUIRED AGENT_SESSION_IN_PROGRESS -> Value.AGENT_SESSION_IN_PROGRESS @@ -628,6 +638,8 @@ private constructor( REALTIME_CALL_INCOMING -> Known.REALTIME_CALL_INCOMING VIDEO_COMPLETED -> Known.VIDEO_COMPLETED VIDEO_FAILED -> Known.VIDEO_FAILED + AGENT_ENVIRONMENT_READY -> Known.AGENT_ENVIRONMENT_READY + AGENT_ENVIRONMENT_FAILED -> Known.AGENT_ENVIRONMENT_FAILED AGENT_SESSION_CREATED -> Known.AGENT_SESSION_CREATED AGENT_SESSION_ACTION_REQUIRED -> Known.AGENT_SESSION_ACTION_REQUIRED AGENT_SESSION_IN_PROGRESS -> Known.AGENT_SESSION_IN_PROGRESS diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookUpdateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookUpdateParams.kt index 8bc46e15a..1f01f0319 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookUpdateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/WebhookUpdateParams.kt @@ -611,6 +611,10 @@ private constructor( @JvmField val VIDEO_FAILED = of("video.failed") + @JvmField val AGENT_ENVIRONMENT_READY = of("agent.environment.ready") + + @JvmField val AGENT_ENVIRONMENT_FAILED = of("agent.environment.failed") + @JvmField val AGENT_SESSION_CREATED = of("agent.session.created") @JvmField val AGENT_SESSION_ACTION_REQUIRED = of("agent.session.action_required") @@ -645,6 +649,8 @@ private constructor( REALTIME_CALL_INCOMING, VIDEO_COMPLETED, VIDEO_FAILED, + AGENT_ENVIRONMENT_READY, + AGENT_ENVIRONMENT_FAILED, AGENT_SESSION_CREATED, AGENT_SESSION_ACTION_REQUIRED, AGENT_SESSION_IN_PROGRESS, @@ -680,6 +686,8 @@ private constructor( REALTIME_CALL_INCOMING, VIDEO_COMPLETED, VIDEO_FAILED, + AGENT_ENVIRONMENT_READY, + AGENT_ENVIRONMENT_FAILED, AGENT_SESSION_CREATED, AGENT_SESSION_ACTION_REQUIRED, AGENT_SESSION_IN_PROGRESS, @@ -718,6 +726,8 @@ private constructor( REALTIME_CALL_INCOMING -> Value.REALTIME_CALL_INCOMING VIDEO_COMPLETED -> Value.VIDEO_COMPLETED VIDEO_FAILED -> Value.VIDEO_FAILED + AGENT_ENVIRONMENT_READY -> Value.AGENT_ENVIRONMENT_READY + AGENT_ENVIRONMENT_FAILED -> Value.AGENT_ENVIRONMENT_FAILED AGENT_SESSION_CREATED -> Value.AGENT_SESSION_CREATED AGENT_SESSION_ACTION_REQUIRED -> Value.AGENT_SESSION_ACTION_REQUIRED AGENT_SESSION_IN_PROGRESS -> Value.AGENT_SESSION_IN_PROGRESS @@ -755,6 +765,8 @@ private constructor( REALTIME_CALL_INCOMING -> Known.REALTIME_CALL_INCOMING VIDEO_COMPLETED -> Known.VIDEO_COMPLETED VIDEO_FAILED -> Known.VIDEO_FAILED + AGENT_ENVIRONMENT_READY -> Known.AGENT_ENVIRONMENT_READY + AGENT_ENVIRONMENT_FAILED -> Known.AGENT_ENVIRONMENT_FAILED AGENT_SESSION_CREATED -> Known.AGENT_SESSION_CREATED AGENT_SESSION_ACTION_REQUIRED -> Known.AGENT_SESSION_ACTION_REQUIRED AGENT_SESSION_IN_PROGRESS -> Known.AGENT_SESSION_IN_PROGRESS diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsync.kt index e9f20ab2b..5411aba18 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsync.kt @@ -5,7 +5,10 @@ package com.openai.services.async.beta.agents import com.openai.core.ClientOptions import com.openai.core.RequestOptions import com.openai.core.http.HttpResponseFor +import com.openai.models.beta.agents.environments.EnvironmentCreateParams import com.openai.models.beta.agents.environments.EnvironmentInfo +import com.openai.models.beta.agents.environments.EnvironmentListPageAsync +import com.openai.models.beta.agents.environments.EnvironmentListParams import com.openai.models.beta.agents.environments.EnvironmentRetrieveParams import com.openai.services.async.beta.agents.environments.FileServiceAsync import com.openai.services.async.beta.agents.environments.TemplateServiceAsync @@ -30,6 +33,19 @@ interface EnvironmentServiceAsync { fun templates(): TemplateServiceAsync + /** + * Creates an OpenAI-hosted environment before creating a session. Requires access to the + * prewarming beta. + */ + fun create(params: EnvironmentCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + /** * Retrieves an execution environment's connection status and safe installed metadata. See * [environment lifecycle](https://developers.openai.com/api/docs/guides/agents-api/environments/lifecycle). @@ -68,6 +84,27 @@ interface EnvironmentServiceAsync { ): CompletableFuture = retrieve(environmentId, EnvironmentRetrieveParams.none(), requestOptions) + /** + * Lists OpenAI-hosted environments owned by the authenticated principal. Requires access to the + * prewarming beta. + */ + fun list(): CompletableFuture = list(EnvironmentListParams.none()) + + /** @see list */ + fun list( + params: EnvironmentListParams = EnvironmentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see list */ + fun list( + params: EnvironmentListParams = EnvironmentListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see list */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(EnvironmentListParams.none(), requestOptions) + /** * A view of [EnvironmentServiceAsync] that provides access to raw HTTP responses for each * method. @@ -87,6 +124,21 @@ interface EnvironmentServiceAsync { fun templates(): TemplateServiceAsync.WithRawResponse + /** + * Returns a raw HTTP response for `post /agents/environments`, but is otherwise the same as + * [EnvironmentServiceAsync.create]. + */ + fun create( + params: EnvironmentCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + /** * Returns a raw HTTP response for `get /agents/environments/{environment_id}`, but is * otherwise the same as [EnvironmentServiceAsync.retrieve]. @@ -127,5 +179,30 @@ interface EnvironmentServiceAsync { requestOptions: RequestOptions, ): CompletableFuture> = retrieve(environmentId, EnvironmentRetrieveParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `get /agents/environments`, but is otherwise the same as + * [EnvironmentServiceAsync.list]. + */ + fun list(): CompletableFuture> = + list(EnvironmentListParams.none()) + + /** @see list */ + fun list( + params: EnvironmentListParams = EnvironmentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see list */ + fun list( + params: EnvironmentListParams = EnvironmentListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see list */ + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(EnvironmentListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncImpl.kt index 031de7b89..d50bb1dd0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncImpl.kt @@ -15,14 +15,20 @@ import com.openai.core.http.HttpRequest import com.openai.core.http.HttpResponse import com.openai.core.http.HttpResponse.Handler import com.openai.core.http.HttpResponseFor +import com.openai.core.http.json import com.openai.core.http.parseable import com.openai.core.prepareAsync +import com.openai.models.beta.agents.environments.EnvironmentCreateParams import com.openai.models.beta.agents.environments.EnvironmentInfo +import com.openai.models.beta.agents.environments.EnvironmentListPageAsync +import com.openai.models.beta.agents.environments.EnvironmentListPageResponse +import com.openai.models.beta.agents.environments.EnvironmentListParams import com.openai.models.beta.agents.environments.EnvironmentRetrieveParams import com.openai.services.async.beta.agents.environments.FileServiceAsync import com.openai.services.async.beta.agents.environments.FileServiceAsyncImpl import com.openai.services.async.beta.agents.environments.TemplateServiceAsync import com.openai.services.async.beta.agents.environments.TemplateServiceAsyncImpl +import java.util.UUID import java.util.concurrent.CompletableFuture import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -52,6 +58,13 @@ class EnvironmentServiceAsyncImpl internal constructor(private val clientOptions override fun templates(): TemplateServiceAsync = templates + override fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /agents/environments + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + override fun retrieve( params: EnvironmentRetrieveParams, requestOptions: RequestOptions, @@ -59,6 +72,13 @@ class EnvironmentServiceAsyncImpl internal constructor(private val clientOptions // get /agents/environments/{environment_id} withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + override fun list( + params: EnvironmentListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /agents/environments + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : EnvironmentServiceAsync.WithRawResponse { @@ -84,6 +104,51 @@ class EnvironmentServiceAsyncImpl internal constructor(private val clientOptions override fun templates(): TemplateServiceAsync.WithRawResponse = templates + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("agents", "environments") + .putAllHeaders(DEFAULT_HEADERS) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync( + clientOptions, + params, + SecurityOptions.builder().bearerAuth(true).build(), + ) + .thenApply { request -> + // Keep one key across retries, while honoring caller-supplied headers. + if (request.headers.values("Idempotency-Key").isNotEmpty()) request + else + request + .toBuilder() + .putHeader("Idempotency-Key", UUID.randomUUID().toString()) + .build() + } + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + private val retrieveHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -121,5 +186,48 @@ class EnvironmentServiceAsyncImpl internal constructor(private val clientOptions } } } + + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun list( + params: EnvironmentListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("agents", "environments") + .putAllHeaders(DEFAULT_HEADERS) + .build() + .prepareAsync( + clientOptions, + params, + SecurityOptions.builder().bearerAuth(true).build(), + ) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + EnvironmentListPageAsync.builder() + .service(EnvironmentServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) + .params(params) + .response(it) + .build() + } + } + } + } } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentService.kt index 0fdd001d7..ec1c2b46c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentService.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentService.kt @@ -6,7 +6,10 @@ import com.google.errorprone.annotations.MustBeClosed import com.openai.core.ClientOptions import com.openai.core.RequestOptions import com.openai.core.http.HttpResponseFor +import com.openai.models.beta.agents.environments.EnvironmentCreateParams import com.openai.models.beta.agents.environments.EnvironmentInfo +import com.openai.models.beta.agents.environments.EnvironmentListPage +import com.openai.models.beta.agents.environments.EnvironmentListParams import com.openai.models.beta.agents.environments.EnvironmentRetrieveParams import com.openai.services.blocking.beta.agents.environments.FileService import com.openai.services.blocking.beta.agents.environments.TemplateService @@ -30,6 +33,19 @@ interface EnvironmentService { fun templates(): TemplateService + /** + * Creates an OpenAI-hosted environment before creating a session. Requires access to the + * prewarming beta. + */ + fun create(params: EnvironmentCreateParams): EnvironmentInfo = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): EnvironmentInfo + /** * Retrieves an execution environment's connection status and safe installed metadata. See * [environment lifecycle](https://developers.openai.com/api/docs/guides/agents-api/environments/lifecycle). @@ -65,6 +81,26 @@ interface EnvironmentService { fun retrieve(environmentId: String, requestOptions: RequestOptions): EnvironmentInfo = retrieve(environmentId, EnvironmentRetrieveParams.none(), requestOptions) + /** + * Lists OpenAI-hosted environments owned by the authenticated principal. Requires access to the + * prewarming beta. + */ + fun list(): EnvironmentListPage = list(EnvironmentListParams.none()) + + /** @see list */ + fun list( + params: EnvironmentListParams = EnvironmentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): EnvironmentListPage + + /** @see list */ + fun list(params: EnvironmentListParams = EnvironmentListParams.none()): EnvironmentListPage = + list(params, RequestOptions.none()) + + /** @see list */ + fun list(requestOptions: RequestOptions): EnvironmentListPage = + list(EnvironmentListParams.none(), requestOptions) + /** * A view of [EnvironmentService] that provides access to raw HTTP responses for each method. */ @@ -83,6 +119,21 @@ interface EnvironmentService { fun templates(): TemplateService.WithRawResponse + /** + * Returns a raw HTTP response for `post /agents/environments`, but is otherwise the same as + * [EnvironmentService.create]. + */ + @MustBeClosed + fun create(params: EnvironmentCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + /** * Returns a raw HTTP response for `get /agents/environments/{environment_id}`, but is * otherwise the same as [EnvironmentService.retrieve]. @@ -126,5 +177,30 @@ interface EnvironmentService { requestOptions: RequestOptions, ): HttpResponseFor = retrieve(environmentId, EnvironmentRetrieveParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `get /agents/environments`, but is otherwise the same as + * [EnvironmentService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(EnvironmentListParams.none()) + + /** @see list */ + @MustBeClosed + fun list( + params: EnvironmentListParams = EnvironmentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see list */ + @MustBeClosed + fun list( + params: EnvironmentListParams = EnvironmentListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see list */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(EnvironmentListParams.none(), requestOptions) } } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceImpl.kt index 960050c4a..aaab7ed93 100644 --- a/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceImpl.kt @@ -15,14 +15,20 @@ import com.openai.core.http.HttpRequest import com.openai.core.http.HttpResponse import com.openai.core.http.HttpResponse.Handler import com.openai.core.http.HttpResponseFor +import com.openai.core.http.json import com.openai.core.http.parseable import com.openai.core.prepare +import com.openai.models.beta.agents.environments.EnvironmentCreateParams import com.openai.models.beta.agents.environments.EnvironmentInfo +import com.openai.models.beta.agents.environments.EnvironmentListPage +import com.openai.models.beta.agents.environments.EnvironmentListPageResponse +import com.openai.models.beta.agents.environments.EnvironmentListParams import com.openai.models.beta.agents.environments.EnvironmentRetrieveParams import com.openai.services.blocking.beta.agents.environments.FileService import com.openai.services.blocking.beta.agents.environments.FileServiceImpl import com.openai.services.blocking.beta.agents.environments.TemplateService import com.openai.services.blocking.beta.agents.environments.TemplateServiceImpl +import java.util.UUID import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -51,6 +57,13 @@ class EnvironmentServiceImpl internal constructor(private val clientOptions: Cli override fun templates(): TemplateService = templates + override fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions, + ): EnvironmentInfo = + // post /agents/environments + withRawResponse().create(params, requestOptions).parse() + override fun retrieve( params: EnvironmentRetrieveParams, requestOptions: RequestOptions, @@ -58,6 +71,13 @@ class EnvironmentServiceImpl internal constructor(private val clientOptions: Cli // get /agents/environments/{environment_id} withRawResponse().retrieve(params, requestOptions).parse() + override fun list( + params: EnvironmentListParams, + requestOptions: RequestOptions, + ): EnvironmentListPage = + // get /agents/environments + withRawResponse().list(params, requestOptions).parse() + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : EnvironmentService.WithRawResponse { @@ -83,6 +103,48 @@ class EnvironmentServiceImpl internal constructor(private val clientOptions: Cli override fun templates(): TemplateService.WithRawResponse = templates + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: EnvironmentCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("agents", "environments") + .putAllHeaders(DEFAULT_HEADERS) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare( + clientOptions, + params, + SecurityOptions.builder().bearerAuth(true).build(), + ) + .let { request -> + // Keep one key across retries, while honoring caller-supplied headers. + if (request.headers.values("Idempotency-Key").isNotEmpty()) request + else + request + .toBuilder() + .putHeader("Idempotency-Key", UUID.randomUUID().toString()) + .build() + } + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + private val retrieveHandler: Handler = jsonHandler(clientOptions.jsonMapper) @@ -117,5 +179,44 @@ class EnvironmentServiceImpl internal constructor(private val clientOptions: Cli } } } + + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun list( + params: EnvironmentListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("agents", "environments") + .putAllHeaders(DEFAULT_HEADERS) + .build() + .prepare( + clientOptions, + params, + SecurityOptions.builder().bearerAuth(true).build(), + ) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + EnvironmentListPage.builder() + .service(EnvironmentServiceImpl(clientOptions)) + .params(params) + .response(it) + .build() + } + } + } } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/EnvironmentParamTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/EnvironmentParamTest.kt index 84c79ac15..61e390433 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/EnvironmentParamTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/EnvironmentParamTest.kt @@ -49,6 +49,7 @@ internal class EnvironmentParamTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .environmentId("xxxxxxxxx") .environmentTemplateId("environment_template_id") .addFile(HostedEnvironmentFileParam.FileId.builder().fileId("x").path("x").build()) .network( @@ -102,6 +103,7 @@ internal class EnvironmentParamTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .environmentId("xxxxxxxxx") .environmentTemplateId("environment_template_id") .addFile( HostedEnvironmentFileParam.FileId.builder().fileId("x").path("x").build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateDiagnosticsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateDiagnosticsTest.kt new file mode 100644 index 000000000..409fc4a0e --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateDiagnosticsTest.kt @@ -0,0 +1,83 @@ +package com.openai.models.beta.agents.environments + +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.models.beta.agents.HostedEnvironmentFileParam +import com.openai.models.beta.agents.HostedPluginParam +import com.openai.models.beta.agents.HostedSkillParam +import com.openai.models.beta.agents.InlineCapabilitySourceParam +import com.openai.models.beta.agents.SetupCommandParam +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class EnvironmentCreateDiagnosticsTest { + @Test + fun hidesConfidentialConfigurationWithoutChangingTheRequest() { + val environment = + EnvironmentCreateParams.Environment.builder() + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty( + "SYNTHETIC_TOKEN", + JsonValue.from("synthetic-private-value"), + ) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("echo synthetic-private-command").build() + ) + .addFile( + HostedEnvironmentFileParam.Inline.builder() + .path("/workspace/example") + .data("ZmlsZQ==") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .name("example") + .description("synthetic description") + .source(InlineCapabilitySourceParam.builder().data("cGx1Z2lu").build()) + .build() + ) + .addSkill( + HostedSkillParam.Inline.builder() + .name("example") + .description("synthetic description") + .source(InlineCapabilitySourceParam.builder().data("c2tpbGw=").build()) + .build() + ) + .putAdditionalProperty("future_config", JsonValue.from("synthetic-future-secret")) + .build() + val params = EnvironmentCreateParams.builder().environment(environment).build() + assertThat(params.toString()) + .doesNotContain( + "synthetic-private-value", + "synthetic-private-command", + "ZmlsZQ==", + "cGx1Z2lu", + "c2tpbGw=", + "synthetic-future-secret", + ) + assertThat(environment.toString()) + .doesNotContain( + "synthetic-private-value", + "synthetic-private-command", + "ZmlsZQ==", + "cGx1Z2lu", + "c2tpbGw=", + "synthetic-future-secret", + ) + val wire = jsonMapper().readTree(jsonMapper().writeValueAsString(params._body())) + assertThat(wire["environment"]["files"][0]["data"].asText()).isEqualTo("ZmlsZQ==") + assertThat(wire["environment"]["plugins"][0]["source"]["data"].asText()) + .isEqualTo("cGx1Z2lu") + assertThat(wire["environment"]["skills"][0]["source"]["data"].asText()) + .isEqualTo("c2tpbGw=") + assertThat(wire["environment"]["future_config"].asText()) + .isEqualTo("synthetic-future-secret") + assertThat(wire["environment"]["env"]["SYNTHETIC_TOKEN"].asText()) + .isEqualTo("synthetic-private-value") + assertThat(wire["environment"]["setup_commands"][0]["command"].asText()) + .isEqualTo("echo synthetic-private-command") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateParamsTest.kt new file mode 100644 index 000000000..87cbe8138 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentCreateParamsTest.kt @@ -0,0 +1,275 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.openai.core.JsonValue +import com.openai.core.http.Headers +import com.openai.models.beta.agents.HostedEnvironmentFileParam +import com.openai.models.beta.agents.HostedPluginParam +import com.openai.models.beta.agents.HostedSkillParam +import com.openai.models.beta.agents.InlineCapabilitySourceParam +import com.openai.models.beta.agents.SetupCommandParam +import kotlin.jvm.optionals.getOrNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class EnvironmentCreateParamsTest { + + @Test + fun create() { + EnvironmentCreateParams.builder() + .idempotencyKey("x") + .environment( + EnvironmentCreateParams.Environment.builder() + .addCapabilityDirectory("string") + .desktop( + EnvironmentCreateParams.Environment.Desktop.builder().enabled(true).build() + ) + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .environmentTemplateId("environment_template_id") + .addFile( + HostedEnvironmentFileParam.FileId.builder().fileId("x").path("x").build() + ) + .network( + EnvironmentCreateParams.Environment.Network.builder() + .access(EnvironmentCreateParams.Environment.Network.Access.ENABLED) + .addAllowedDomain("string") + .addBlockedDomain("string") + .build() + ) + .packages( + EnvironmentCreateParams.Environment.Packages.builder() + .addNpm("string") + .addPython("string") + .addSystem("string") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .description("description") + .name("x") + .source(InlineCapabilitySourceParam.builder().data("x").build()) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("command").cwd("cwd").build() + ) + .addSkill( + HostedSkillParam.SkillReference.builder() + .skillId("x") + .version("version") + .build() + ) + .build() + ) + .addVaultId("string") + .build() + } + + @Test + fun headers() { + val params = + EnvironmentCreateParams.builder() + .idempotencyKey("x") + .environment( + EnvironmentCreateParams.Environment.builder() + .addCapabilityDirectory("string") + .desktop( + EnvironmentCreateParams.Environment.Desktop.builder() + .enabled(true) + .build() + ) + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .environmentTemplateId("environment_template_id") + .addFile( + HostedEnvironmentFileParam.FileId.builder() + .fileId("x") + .path("x") + .build() + ) + .network( + EnvironmentCreateParams.Environment.Network.builder() + .access(EnvironmentCreateParams.Environment.Network.Access.ENABLED) + .addAllowedDomain("string") + .addBlockedDomain("string") + .build() + ) + .packages( + EnvironmentCreateParams.Environment.Packages.builder() + .addNpm("string") + .addPython("string") + .addSystem("string") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .description("description") + .name("x") + .source(InlineCapabilitySourceParam.builder().data("x").build()) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("command").cwd("cwd").build() + ) + .addSkill( + HostedSkillParam.SkillReference.builder() + .skillId("x") + .version("version") + .build() + ) + .build() + ) + .addVaultId("string") + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().put("Idempotency-Key", "x").build()) + } + + @Test + fun headersWithoutOptionalFields() { + val params = + EnvironmentCreateParams.builder() + .environment(EnvironmentCreateParams.Environment.builder().build()) + .build() + + val headers = params._headers() + + assertThat(headers).isEqualTo(Headers.builder().build()) + } + + @Test + fun body() { + val params = + EnvironmentCreateParams.builder() + .idempotencyKey("x") + .environment( + EnvironmentCreateParams.Environment.builder() + .addCapabilityDirectory("string") + .desktop( + EnvironmentCreateParams.Environment.Desktop.builder() + .enabled(true) + .build() + ) + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .environmentTemplateId("environment_template_id") + .addFile( + HostedEnvironmentFileParam.FileId.builder() + .fileId("x") + .path("x") + .build() + ) + .network( + EnvironmentCreateParams.Environment.Network.builder() + .access(EnvironmentCreateParams.Environment.Network.Access.ENABLED) + .addAllowedDomain("string") + .addBlockedDomain("string") + .build() + ) + .packages( + EnvironmentCreateParams.Environment.Packages.builder() + .addNpm("string") + .addPython("string") + .addSystem("string") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .description("description") + .name("x") + .source(InlineCapabilitySourceParam.builder().data("x").build()) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("command").cwd("cwd").build() + ) + .addSkill( + HostedSkillParam.SkillReference.builder() + .skillId("x") + .version("version") + .build() + ) + .build() + ) + .addVaultId("string") + .build() + + val body = params._body() + + assertThat(body.environment()) + .isEqualTo( + EnvironmentCreateParams.Environment.builder() + .addCapabilityDirectory("string") + .desktop( + EnvironmentCreateParams.Environment.Desktop.builder().enabled(true).build() + ) + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .environmentTemplateId("environment_template_id") + .addFile( + HostedEnvironmentFileParam.FileId.builder().fileId("x").path("x").build() + ) + .network( + EnvironmentCreateParams.Environment.Network.builder() + .access(EnvironmentCreateParams.Environment.Network.Access.ENABLED) + .addAllowedDomain("string") + .addBlockedDomain("string") + .build() + ) + .packages( + EnvironmentCreateParams.Environment.Packages.builder() + .addNpm("string") + .addPython("string") + .addSystem("string") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .description("description") + .name("x") + .source(InlineCapabilitySourceParam.builder().data("x").build()) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("command").cwd("cwd").build() + ) + .addSkill( + HostedSkillParam.SkillReference.builder() + .skillId("x") + .version("version") + .build() + ) + .build() + ) + assertThat(body.vaultIds().getOrNull()).containsExactly("string") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + EnvironmentCreateParams.builder() + .environment(EnvironmentCreateParams.Environment.builder().build()) + .build() + + val body = params._body() + + assertThat(body.environment()) + .isEqualTo(EnvironmentCreateParams.Environment.builder().build()) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageResponseTest.kt new file mode 100644 index 000000000..256e5ef70 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentListPageResponseTest.kt @@ -0,0 +1,126 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import com.openai.models.beta.agents.HostedEnvironmentFileId +import com.openai.models.beta.agents.HostedPlugin +import com.openai.models.beta.agents.HostedSkillReference +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class EnvironmentListPageResponseTest { + + @Test + fun create() { + val environmentListPageResponse = + EnvironmentListPageResponse.builder() + .addData( + EnvironmentInfo.builder() + .id("id") + .addFile( + HostedEnvironmentFileId.builder() + .id("id") + .fileId("file_id") + .path("path") + .sizeBytes(0L) + .build() + ) + .addPlugin( + HostedPlugin.builder().description("description").name("name").build() + ) + .addSkill( + HostedSkillReference.builder() + .description("description") + .name("name") + .skillId("skill_id") + .version("version") + .build() + ) + .status(EnvironmentInfo.Status.PENDING) + .type(EnvironmentInfo.Type.OPENAI_HOSTED) + .build() + ) + .firstId("first_id") + .hasMore(true) + .lastId("last_id") + .build() + + assertThat(environmentListPageResponse.data()) + .containsExactly( + EnvironmentInfo.builder() + .id("id") + .addFile( + HostedEnvironmentFileId.builder() + .id("id") + .fileId("file_id") + .path("path") + .sizeBytes(0L) + .build() + ) + .addPlugin( + HostedPlugin.builder().description("description").name("name").build() + ) + .addSkill( + HostedSkillReference.builder() + .description("description") + .name("name") + .skillId("skill_id") + .version("version") + .build() + ) + .status(EnvironmentInfo.Status.PENDING) + .type(EnvironmentInfo.Type.OPENAI_HOSTED) + .build() + ) + assertThat(environmentListPageResponse.firstId()).contains("first_id") + assertThat(environmentListPageResponse.hasMore()).isEqualTo(true) + assertThat(environmentListPageResponse.lastId()).contains("last_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val environmentListPageResponse = + EnvironmentListPageResponse.builder() + .addData( + EnvironmentInfo.builder() + .id("id") + .addFile( + HostedEnvironmentFileId.builder() + .id("id") + .fileId("file_id") + .path("path") + .sizeBytes(0L) + .build() + ) + .addPlugin( + HostedPlugin.builder().description("description").name("name").build() + ) + .addSkill( + HostedSkillReference.builder() + .description("description") + .name("name") + .skillId("skill_id") + .version("version") + .build() + ) + .status(EnvironmentInfo.Status.PENDING) + .type(EnvironmentInfo.Type.OPENAI_HOSTED) + .build() + ) + .firstId("first_id") + .hasMore(true) + .lastId("last_id") + .build() + + val roundtrippedEnvironmentListPageResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(environmentListPageResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedEnvironmentListPageResponse).isEqualTo(environmentListPageResponse) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentListParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentListParamsTest.kt new file mode 100644 index 000000000..16536cacf --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/agents/environments/EnvironmentListParamsTest.kt @@ -0,0 +1,52 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.agents.environments + +import com.openai.core.http.QueryParams +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class EnvironmentListParamsTest { + + @Test + fun create() { + EnvironmentListParams.builder() + .after("after") + .limit(1L) + .order(EnvironmentListParams.Order.ASC) + .type(EnvironmentListParams.Type.OPENAI_HOSTED) + .build() + } + + @Test + fun queryParams() { + val params = + EnvironmentListParams.builder() + .after("after") + .limit(1L) + .order(EnvironmentListParams.Order.ASC) + .type(EnvironmentListParams.Type.OPENAI_HOSTED) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("after", "after") + .put("limit", "1") + .put("order", "asc") + .put("type", "openai_hosted") + .build() + ) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = EnvironmentListParams.builder().build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/AgentEnvironmentFailedWebhookEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/AgentEnvironmentFailedWebhookEventTest.kt new file mode 100644 index 000000000..b33b24e88 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/AgentEnvironmentFailedWebhookEventTest.kt @@ -0,0 +1,46 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AgentEnvironmentFailedWebhookEventTest { + + @Test + fun create() { + val agentEnvironmentFailedWebhookEvent = + AgentEnvironmentFailedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentFailedWebhookEvent.Data.builder().id("id").build()) + .build() + + assertThat(agentEnvironmentFailedWebhookEvent.id()).isEqualTo("id") + assertThat(agentEnvironmentFailedWebhookEvent.createdAt()).isEqualTo(0L) + assertThat(agentEnvironmentFailedWebhookEvent.data()) + .isEqualTo(AgentEnvironmentFailedWebhookEvent.Data.builder().id("id").build()) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val agentEnvironmentFailedWebhookEvent = + AgentEnvironmentFailedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentFailedWebhookEvent.Data.builder().id("id").build()) + .build() + + val roundtrippedAgentEnvironmentFailedWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(agentEnvironmentFailedWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedAgentEnvironmentFailedWebhookEvent) + .isEqualTo(agentEnvironmentFailedWebhookEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/AgentEnvironmentReadyWebhookEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/AgentEnvironmentReadyWebhookEventTest.kt new file mode 100644 index 000000000..a3ac1ff63 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/AgentEnvironmentReadyWebhookEventTest.kt @@ -0,0 +1,46 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AgentEnvironmentReadyWebhookEventTest { + + @Test + fun create() { + val agentEnvironmentReadyWebhookEvent = + AgentEnvironmentReadyWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentReadyWebhookEvent.Data.builder().id("id").build()) + .build() + + assertThat(agentEnvironmentReadyWebhookEvent.id()).isEqualTo("id") + assertThat(agentEnvironmentReadyWebhookEvent.createdAt()).isEqualTo(0L) + assertThat(agentEnvironmentReadyWebhookEvent.data()) + .isEqualTo(AgentEnvironmentReadyWebhookEvent.Data.builder().id("id").build()) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val agentEnvironmentReadyWebhookEvent = + AgentEnvironmentReadyWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentReadyWebhookEvent.Data.builder().id("id").build()) + .build() + + val roundtrippedAgentEnvironmentReadyWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(agentEnvironmentReadyWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedAgentEnvironmentReadyWebhookEvent) + .isEqualTo(agentEnvironmentReadyWebhookEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt index 3e00b8854..2d18be286 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt @@ -14,6 +14,130 @@ import org.junit.jupiter.params.provider.EnumSource internal class UnwrapWebhookEventTest { + @Test + fun ofAgentEnvironmentFailed() { + val agentEnvironmentFailed = + AgentEnvironmentFailedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentFailedWebhookEvent.Data.builder().id("id").build()) + .build() + + val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentEnvironmentFailed(agentEnvironmentFailed) + + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).contains(agentEnvironmentFailed) + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionIdle()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionInProgress()).isEmpty + assertThat(unwrapWebhookEvent.batchCancelled()).isEmpty + assertThat(unwrapWebhookEvent.batchCompleted()).isEmpty + assertThat(unwrapWebhookEvent.batchExpired()).isEmpty + assertThat(unwrapWebhookEvent.batchFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunCanceled()).isEmpty + assertThat(unwrapWebhookEvent.evalRunFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobCancelled()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobFailed()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.liveCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.liveTransportIncoming()).isEmpty + assertThat(unwrapWebhookEvent.realtimeCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.responseCancelled()).isEmpty + assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty + assertThat(unwrapWebhookEvent.responseFailed()).isEmpty + assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyDeactivationIssued()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyWarningIssued()).isEmpty + } + + @Test + fun ofAgentEnvironmentFailedRoundtrip() { + val jsonMapper = jsonMapper() + val unwrapWebhookEvent = + UnwrapWebhookEvent.ofAgentEnvironmentFailed( + AgentEnvironmentFailedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentFailedWebhookEvent.Data.builder().id("id").build()) + .build() + ) + + val roundtrippedUnwrapWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(unwrapWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedUnwrapWebhookEvent).isEqualTo(unwrapWebhookEvent) + } + + @Test + fun ofAgentEnvironmentReady() { + val agentEnvironmentReady = + AgentEnvironmentReadyWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentReadyWebhookEvent.Data.builder().id("id").build()) + .build() + + val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentEnvironmentReady(agentEnvironmentReady) + + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).contains(agentEnvironmentReady) + assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionIdle()).isEmpty + assertThat(unwrapWebhookEvent.agentSessionInProgress()).isEmpty + assertThat(unwrapWebhookEvent.batchCancelled()).isEmpty + assertThat(unwrapWebhookEvent.batchCompleted()).isEmpty + assertThat(unwrapWebhookEvent.batchExpired()).isEmpty + assertThat(unwrapWebhookEvent.batchFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunCanceled()).isEmpty + assertThat(unwrapWebhookEvent.evalRunFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobCancelled()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobFailed()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.liveCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.liveTransportIncoming()).isEmpty + assertThat(unwrapWebhookEvent.realtimeCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.responseCancelled()).isEmpty + assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty + assertThat(unwrapWebhookEvent.responseFailed()).isEmpty + assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyDeactivationIssued()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyWarningIssued()).isEmpty + } + + @Test + fun ofAgentEnvironmentReadyRoundtrip() { + val jsonMapper = jsonMapper() + val unwrapWebhookEvent = + UnwrapWebhookEvent.ofAgentEnvironmentReady( + AgentEnvironmentReadyWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data(AgentEnvironmentReadyWebhookEvent.Data.builder().id("id").build()) + .build() + ) + + val roundtrippedUnwrapWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(unwrapWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedUnwrapWebhookEvent).isEqualTo(unwrapWebhookEvent) + } + @Test fun ofAgentSessionActionRequired() { val agentSessionActionRequired = @@ -38,6 +162,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentSessionActionRequired(agentSessionActionRequired) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()) .contains(agentSessionActionRequired) assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty @@ -123,6 +249,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentSessionCreated(agentSessionCreated) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).contains(agentSessionCreated) assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -200,6 +328,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentSessionFailed(agentSessionFailed) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).contains(agentSessionFailed) @@ -272,6 +402,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentSessionIdle(agentSessionIdle) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -344,6 +476,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofAgentSessionInProgress(agentSessionInProgress) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -411,6 +545,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofBatchCancelled(batchCancelled) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -473,6 +609,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofBatchCompleted(batchCompleted) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -535,6 +673,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofBatchExpired(batchExpired) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -597,6 +737,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofBatchFailed(batchFailed) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -659,6 +801,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofEvalRunCanceled(evalRunCanceled) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -721,6 +865,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofEvalRunFailed(evalRunFailed) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -783,6 +929,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofEvalRunSucceeded(evalRunSucceeded) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -845,6 +993,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofFineTuningJobCancelled(fineTuningJobCancelled) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -907,6 +1057,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofFineTuningJobFailed(fineTuningJobFailed) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -969,6 +1121,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofFineTuningJobSucceeded(fineTuningJobSucceeded) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1042,6 +1196,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofLiveCallIncoming(liveCallIncoming) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1130,6 +1286,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofLiveTransportIncoming(liveTransportIncoming) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1218,6 +1376,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofRealtimeCallIncoming(realtimeCallIncoming) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1293,6 +1453,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofResponseCancelled(responseCancelled) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1355,6 +1517,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofResponseCompleted(responseCompleted) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1417,6 +1581,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofResponseFailed(responseFailed) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1479,6 +1645,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofResponseIncomplete(responseIncomplete) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1544,6 +1712,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofSafetyAlertCreated(safetyAlertCreated) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1609,6 +1779,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofSafetyDeactivationIssued(safetyDeactivationIssued) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1673,6 +1845,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofSafetyOrgAlertCreated(safetyOrgAlertCreated) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty @@ -1737,6 +1911,8 @@ internal class UnwrapWebhookEventTest { val unwrapWebhookEvent = UnwrapWebhookEvent.ofSafetyWarningIssued(safetyWarningIssued) + assertThat(unwrapWebhookEvent.agentEnvironmentFailed()).isEmpty + assertThat(unwrapWebhookEvent.agentEnvironmentReady()).isEmpty assertThat(unwrapWebhookEvent.agentSessionActionRequired()).isEmpty assertThat(unwrapWebhookEvent.agentSessionCreated()).isEmpty assertThat(unwrapWebhookEvent.agentSessionFailed()).isEmpty diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncTest.kt index 508b17c79..6679813d2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/agents/EnvironmentServiceAsyncTest.kt @@ -2,14 +2,111 @@ package com.openai.services.async.beta.agents +import com.github.tomakehurst.wiremock.client.WireMock.anyUrl +import com.github.tomakehurst.wiremock.client.WireMock.findAll +import com.github.tomakehurst.wiremock.client.WireMock.get +import com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor +import com.github.tomakehurst.wiremock.client.WireMock.okJson +import com.github.tomakehurst.wiremock.client.WireMock.reset +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClientAsync +import com.openai.core.JsonValue +import com.openai.models.beta.agents.HostedEnvironmentFileParam +import com.openai.models.beta.agents.HostedPluginParam +import com.openai.models.beta.agents.HostedSkillParam +import com.openai.models.beta.agents.InlineCapabilitySourceParam +import com.openai.models.beta.agents.SetupCommandParam +import com.openai.models.beta.agents.environments.EnvironmentCreateParams +import java.util.concurrent.atomic.AtomicInteger +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.parallel.ResourceLock @ExtendWith(TestServerExtension::class) +@WireMockTest +@ResourceLock("https://github.com/wiremock/wiremock/issues/169") internal class EnvironmentServiceAsyncTest { + @Test + fun create() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + val environmentServiceAsync = client.beta().agents().environments() + + val environmentInfoFuture = + environmentServiceAsync.create( + EnvironmentCreateParams.builder() + .idempotencyKey("x") + .environment( + EnvironmentCreateParams.Environment.builder() + .addCapabilityDirectory("string") + .desktop( + EnvironmentCreateParams.Environment.Desktop.builder() + .enabled(true) + .build() + ) + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .environmentTemplateId("environment_template_id") + .addFile( + HostedEnvironmentFileParam.FileId.builder() + .fileId("x") + .path("x") + .build() + ) + .network( + EnvironmentCreateParams.Environment.Network.builder() + .access( + EnvironmentCreateParams.Environment.Network.Access.ENABLED + ) + .addAllowedDomain("string") + .addBlockedDomain("string") + .build() + ) + .packages( + EnvironmentCreateParams.Environment.Packages.builder() + .addNpm("string") + .addPython("string") + .addSystem("string") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .description("description") + .name("x") + .source(InlineCapabilitySourceParam.builder().data("x").build()) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("command").cwd("cwd").build() + ) + .addSkill( + HostedSkillParam.SkillReference.builder() + .skillId("x") + .version("version") + .build() + ) + .build() + ) + .addVaultId("string") + .build() + ) + + val environmentInfo = environmentInfoFuture.get() + environmentInfo.validate() + } + @Test fun retrieve() { val client = @@ -25,4 +122,99 @@ internal class EnvironmentServiceAsyncTest { val environmentInfo = environmentInfoFuture.get() environmentInfo.validate() } + + @Test + fun listStopsOnExplicitFalse(wmRuntimeInfo: WireMockRuntimeInfo) { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + try { + // A terminal page can still contain items and a cursor + stubFor( + get(anyUrl()) + .willReturn(okJson("{\"data\":[{\"id\":\"item_1\"}],\"has_more\":false}")) + ) + val page = client.beta().agents().environments().list().get() + assertThat(page.items()).hasSize(1) + assertThat(page.hasNextPage()).isFalse() + + val count = AtomicInteger() + page.autoPager().subscribe { count.incrementAndGet() }.onCompleteFuture().get() + assertThat(count.get()).isEqualTo(1) + + assertThat(findAll(getRequestedFor(anyUrl()))).hasSize(1) + } finally { + client.close() + } + } + + @Test + fun listContinuesUntilExplicitFalse(wmRuntimeInfo: WireMockRuntimeInfo) { + // Both explicit true and a missing flag preserve normal cursor traversal. + for (firstResponse in + listOf( + "{\"data\":[{\"id\":\"item_1\"}],\"has_more\":true}", + "{\"data\":[{\"id\":\"item_1\"}]}", + )) { + reset() + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + try { + stubFor( + get(anyUrl()) + .inScenario("pagination") + .whenScenarioStateIs("Started") + .willReturn(okJson(firstResponse)) + .willSetStateTo("terminal") + ) + stubFor( + get(anyUrl()) + .inScenario("pagination") + .whenScenarioStateIs("terminal") + .willReturn(okJson("{\"data\":[{\"id\":\"item_1\"}],\"has_more\":false}")) + .willSetStateTo("unexpected") + ) + // Bound a regression to one extra request instead of an infinite loop. + stubFor( + get(anyUrl()) + .inScenario("pagination") + .whenScenarioStateIs("unexpected") + .willReturn(okJson("{}")) + ) + val page = client.beta().agents().environments().list().get() + assertThat(page.hasNextPage()).isTrue() + + val count = AtomicInteger() + page.autoPager().subscribe { count.incrementAndGet() }.onCompleteFuture().get() + assertThat(count.get()).isEqualTo(2) + + assertThat(findAll(getRequestedFor(anyUrl()))).hasSize(2) + } finally { + client.close() + } + } + } + + @Test + fun list() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + val environmentServiceAsync = client.beta().agents().environments() + + val pageFuture = environmentServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/beta/agents/AgentTurnResultsTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/beta/agents/AgentTurnResultsTest.kt index ec0da6a7a..096bd0aa0 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/beta/agents/AgentTurnResultsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/beta/agents/AgentTurnResultsTest.kt @@ -17,6 +17,7 @@ import io.swagger.v3.oas.annotations.media.Schema import java.io.ByteArrayInputStream import java.util.Optional import java.util.concurrent.CompletableFuture +import java.util.concurrent.CountDownLatch import java.util.concurrent.Executor import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger @@ -261,6 +262,7 @@ internal class AgentTurnResultsTest { var executor: Executor = direct val posts = AtomicInteger() val closed = AtomicInteger() + val responseClosed = CountDownLatch(1) override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { val streaming = @@ -302,6 +304,7 @@ internal class AgentTurnResultsTest { override fun close() { closed.incrementAndGet() + responseClosed.countDown() } } } @@ -812,7 +815,8 @@ internal class AgentTurnResultsTest { stream.onCompleteFuture().get(5, TimeUnit.SECONDS) assertThat(AgentTurnResults.getFinalResult(stream).isCancelled).isTrue() transport.responseReady.complete(null) - assertThat(transport.closed.get()).isPositive() + // The request may still be opening after observation has been cancelled. + assertThat(transport.responseClosed.await(5, TimeUnit.SECONDS)).isTrue() } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceTest.kt index 968513ed9..951ee3564 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/EnvironmentServiceTest.kt @@ -2,14 +2,109 @@ package com.openai.services.blocking.beta.agents +import com.github.tomakehurst.wiremock.client.WireMock.anyUrl +import com.github.tomakehurst.wiremock.client.WireMock.findAll +import com.github.tomakehurst.wiremock.client.WireMock.get +import com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor +import com.github.tomakehurst.wiremock.client.WireMock.okJson +import com.github.tomakehurst.wiremock.client.WireMock.reset +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo +import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.openai.TestServerExtension import com.openai.client.okhttp.OpenAIOkHttpClient +import com.openai.core.JsonValue +import com.openai.models.beta.agents.HostedEnvironmentFileParam +import com.openai.models.beta.agents.HostedPluginParam +import com.openai.models.beta.agents.HostedSkillParam +import com.openai.models.beta.agents.InlineCapabilitySourceParam +import com.openai.models.beta.agents.SetupCommandParam +import com.openai.models.beta.agents.environments.EnvironmentCreateParams +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.parallel.ResourceLock @ExtendWith(TestServerExtension::class) +@WireMockTest +@ResourceLock("https://github.com/wiremock/wiremock/issues/169") internal class EnvironmentServiceTest { + @Test + fun create() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + val environmentService = client.beta().agents().environments() + + val environmentInfo = + environmentService.create( + EnvironmentCreateParams.builder() + .idempotencyKey("x") + .environment( + EnvironmentCreateParams.Environment.builder() + .addCapabilityDirectory("string") + .desktop( + EnvironmentCreateParams.Environment.Desktop.builder() + .enabled(true) + .build() + ) + .env( + EnvironmentCreateParams.Environment.Env.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .environmentTemplateId("environment_template_id") + .addFile( + HostedEnvironmentFileParam.FileId.builder() + .fileId("x") + .path("x") + .build() + ) + .network( + EnvironmentCreateParams.Environment.Network.builder() + .access( + EnvironmentCreateParams.Environment.Network.Access.ENABLED + ) + .addAllowedDomain("string") + .addBlockedDomain("string") + .build() + ) + .packages( + EnvironmentCreateParams.Environment.Packages.builder() + .addNpm("string") + .addPython("string") + .addSystem("string") + .build() + ) + .addPlugin( + HostedPluginParam.builder() + .description("description") + .name("x") + .source(InlineCapabilitySourceParam.builder().data("x").build()) + .build() + ) + .addSetupCommand( + SetupCommandParam.builder().command("command").cwd("cwd").build() + ) + .addSkill( + HostedSkillParam.SkillReference.builder() + .skillId("x") + .version("version") + .build() + ) + .build() + ) + .addVaultId("string") + .build() + ) + + environmentInfo.validate() + } + @Test fun retrieve() { val client = @@ -24,4 +119,94 @@ internal class EnvironmentServiceTest { environmentInfo.validate() } + + @Test + fun listStopsOnExplicitFalse(wmRuntimeInfo: WireMockRuntimeInfo) { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + try { + // A terminal page can still contain items and a cursor + stubFor( + get(anyUrl()) + .willReturn(okJson("{\"data\":[{\"id\":\"item_1\"}],\"has_more\":false}")) + ) + val page = client.beta().agents().environments().list() + assertThat(page.items()).hasSize(1) + assertThat(page.hasNextPage()).isFalse() + + assertThat(page.autoPager().toList()).hasSize(1) + + assertThat(findAll(getRequestedFor(anyUrl()))).hasSize(1) + } finally { + client.close() + } + } + + @Test + fun listContinuesUntilExplicitFalse(wmRuntimeInfo: WireMockRuntimeInfo) { + // Both explicit true and a missing flag preserve normal cursor traversal. + for (firstResponse in + listOf( + "{\"data\":[{\"id\":\"item_1\"}],\"has_more\":true}", + "{\"data\":[{\"id\":\"item_1\"}]}", + )) { + reset() + val client = + OpenAIOkHttpClient.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + try { + stubFor( + get(anyUrl()) + .inScenario("pagination") + .whenScenarioStateIs("Started") + .willReturn(okJson(firstResponse)) + .willSetStateTo("terminal") + ) + stubFor( + get(anyUrl()) + .inScenario("pagination") + .whenScenarioStateIs("terminal") + .willReturn(okJson("{\"data\":[{\"id\":\"item_1\"}],\"has_more\":false}")) + .willSetStateTo("unexpected") + ) + // Bound a regression to one extra request instead of an infinite loop. + stubFor( + get(anyUrl()) + .inScenario("pagination") + .whenScenarioStateIs("unexpected") + .willReturn(okJson("{}")) + ) + val page = client.beta().agents().environments().list() + assertThat(page.hasNextPage()).isTrue() + + assertThat(page.autoPager().toList()).hasSize(2) + + assertThat(findAll(getRequestedFor(anyUrl()))).hasSize(2) + } finally { + client.close() + } + } + } + + @Test + fun list() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + val environmentService = client.beta().agents().environments() + + val page = environmentService.list() + + page.response().validate() + } } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/environments/EnvironmentCreateRetryTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/environments/EnvironmentCreateRetryTest.kt new file mode 100644 index 000000000..93083a02b --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/agents/environments/EnvironmentCreateRetryTest.kt @@ -0,0 +1,72 @@ +package com.openai.services.blocking.beta.agents.environments + +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.WireMock.* +import com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig +import com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED +import com.openai.client.okhttp.OpenAIOkHttpClient +import com.openai.models.beta.agents.environments.EnvironmentCreateParams +import java.util.concurrent.TimeUnit +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +internal class EnvironmentCreateRetryTest { + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun retriesKeepOneKeyPerLogicalCreate(async: Boolean) { + val server = WireMockServer(wireMockConfig().dynamicPort()) + server.start() + try { + server.stubFor( + post(urlEqualTo("/agents/environments")) + .inScenario("retry") + .whenScenarioStateIs(STARTED) + .willReturn(aResponse().withStatus(500).withHeader("retry-after", "0")) + .willSetStateTo("retry") + ) + server.stubFor( + post(urlEqualTo("/agents/environments")) + .inScenario("retry") + .whenScenarioStateIs("retry") + .willReturn(okJson("""{"id":"env_test","object":"agent.environment"}""")) + .willSetStateTo(STARTED) + ) + val client = + OpenAIOkHttpClient.builder() + .apiKey("synthetic") + .baseUrl(server.baseUrl()) + .maxRetries(1) + .build() + try { + for (explicit in listOf(false, false, true)) { + val params = + EnvironmentCreateParams.builder() + .environment(EnvironmentCreateParams.Environment.builder().build()) + .apply { if (explicit) idempotencyKey("caller-key") } + .build() + if (async) + client + .async() + .beta() + .agents() + .environments() + .create(params) + .get(30, TimeUnit.SECONDS) + else client.beta().agents().environments().create(params) + } + val requests = server.findAll(postRequestedFor(urlEqualTo("/agents/environments"))) + assertThat(requests).hasSize(6) + val keys = requests.map { it.getHeader("Idempotency-Key") } + assertThat(keys).allSatisfy { assertThat(it).isNotBlank() } + assertThat(keys[0]).isEqualTo(keys[1]).isNotEqualTo(keys[2]) + assertThat(keys[2]).isEqualTo(keys[3]) + assertThat(keys.takeLast(2)).containsOnly("caller-key") + } finally { + client.close() + } + } finally { + server.stop() + } + } +}