diff --git a/.fern/metadata.json b/.fern/metadata.json index 7c8be26..acc009c 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,5 +1,5 @@ { - "cliVersion": "3.5.0", + "cliVersion": "3.27.0", "generatorName": "fernapi/fern-java-sdk", "generatorVersion": "3.18.5", "generatorConfig": { diff --git a/README.md b/README.md index 482f453..89c7e89 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Add the dependency in your `pom.xml` file: com.anduril lattice-sdk - 5.0.0 + 5.1.0 ``` diff --git a/build.gradle b/build.gradle index f7d7e49..1081a6d 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ java { group = 'com.anduril' -version = '5.0.0' +version = '5.1.0' jar { dependsOn(":generatePomFileForMavenPublication") @@ -78,21 +78,21 @@ publishing { maven(MavenPublication) { groupId = 'com.anduril' artifactId = 'lattice-sdk' - version = '5.0.0' + version = '5.1.0' from components.java pom { - name = 'Anduril Industries, Inc.' - description = 'Anduril Lattice SDK for Java' - url = 'https://developer.anduril.com' + name = 'anduril' + description = 'The official SDK of anduril' + url = 'https://buildwithfern.com' licenses { license { - name = 'Anduril Lattice Software Development Kit License Agreement' + name = 'Custom License (LICENSE)' } } developers { developer { - name = 'Anduril Industries, Inc.' - email = 'lattice-developers@anduril.com' + name = 'anduril' + email = 'developers@anduril.com' } } scm { diff --git a/reference.md b/reference.md new file mode 100644 index 0000000..4cbc8d3 --- /dev/null +++ b/reference.md @@ -0,0 +1,1326 @@ +# Reference +## Entities +
client.entities.publishEntity(request) -> Entity +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Publish an entity for ingest into the Entities API. Entities created with this method are "owned" by the originator: other sources, +such as the UI, may not edit or delete these entities. The server validates entities at API call time and +returns an error if the entity is invalid. + +An entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist +then it will be created. Otherwise the entity will be updated. An entity will only be updated if its +provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.entities().publishEntity( + Entity + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Entity` + +
+
+
+
+ + +
+
+
+ +
client.entities.getEntity(entityId) -> Entity +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.entities().getEntity( + "entityId", + GetEntityRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**entityId:** `String` — ID of the entity to return + +
+
+
+
+ + +
+
+
+ +
client.entities.overrideEntity(entityId, fieldPath, request) -> Entity +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Only fields marked with overridable can be overridden. Please refer to our documentation to see the comprehensive +list of fields that can be overridden. The entity in the request body should only have a value set on the field +specified in the field path parameter. Field paths are rooted in the base entity object and must be represented +using lower_snake_case. Do not include "entity" in the field path. + +Note that overrides are applied in an eventually consistent manner. If multiple overrides are created +concurrently for the same field path, the last writer wins. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.entities().overrideEntity( + "entityId", + "mil_view.disposition", + EntityOverride + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**entityId:** `String` — The unique ID of the entity to override + +
+
+ +
+
+ +**fieldPath:** `String` — fieldPath to override + +
+
+ +
+
+ +**entity:** `Optional` + +The entity containing the overridden fields. The service will extract the overridable fields from +the object and ignore all other fields. + +
+
+ +
+
+ +**provenance:** `Optional` — Additional information about the source of the override. + +
+
+
+
+ + +
+
+
+ +
client.entities.removeEntityOverride(entityId, fieldPath) -> Entity +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This operation clears the override value from the specified field path on the entity. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.entities().removeEntityOverride( + "entityId", + "mil_view.disposition", + RemoveEntityOverrideRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**entityId:** `String` — The unique ID of the entity to undo an override from. + +
+
+ +
+
+ +**fieldPath:** `String` — The fieldPath to clear overrides from. + +
+
+
+
+ + +
+
+
+ +
client.entities.longPollEntityEvents(request) -> EntityEventResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This is a long polling API that will first return all pre-existing data and then return all new data as +it becomes available. If you want to start a new polling session then open a request with an empty +'sessionToken' in the request body. The server will return a new session token in the response. +If you want to retrieve the next batch of results from an existing polling session then send the session +token you received from the server in the request body. If no new data is available then the server will +hold the connection open for up to 5 minutes. After the 5 minute timeout period, the server will close the +connection with no results and you may resume polling with the same session token. If your session falls behind +more than 3x the total number of entities in the environment, the server will terminate your session. +In this case you must start a new session by sending a request with an empty session token. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.entities().longPollEntityEvents( + EntityEventRequest + .builder() + .sessionToken("sessionToken") + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**sessionToken:** `String` — Long-poll session identifier. Leave empty to start a new polling session. + +
+
+ +
+
+ +**batchSize:** `Optional` — Maximum size of response batch. Defaults to 100. Must be between 1 and 2000 (inclusive). + +
+
+
+
+ + +
+
+
+ +
client.entities.streamEntities(request) -> Optional<StreamEntitiesResponse> +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Establishes a server-sent events (SSE) connection that streams entity data in real-time. +This is a one-way connection from server to client that follows the SSE protocol with text/event-stream content type. + +This endpoint enables clients to maintain a real-time view of the common operational picture (COP) +by first streaming all pre-existing entities that match filter criteria, then continuously delivering +updates as entities are created, modified, or deleted. + +The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, +then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open +indefinitely unless preExistingOnly is set to true. + +Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS +parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive. + +Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. +This allows receiving only relevant data instead of complete entities. + +The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, +this provides real-time updates with minimal latency and reduced server load. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.entities().streamEntities( + EntityStreamRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**heartbeatIntervalMs:** `Optional` — at what interval to send heartbeat events, defaults to 30s. + +
+
+ +
+
+ +**preExistingOnly:** `Optional` — only stream pre-existing entities in the environment and then close the connection, defaults to false. + +
+
+ +
+
+ +**componentsToInclude:** `Optional>` — list of components to include, leave empty to include all components. + +
+
+
+
+ + +
+
+
+ +## Tasks +
client.tasks.createTask(request) -> Task +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Creates a new Task in the system with the specified parameters. + +This method initiates a new task with a unique ID (either provided or auto-generated), +sets the initial task state to STATUS_CREATED, and establishes task ownership. The task +can be assigned to a specific agent through the Relations field. + +Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed +through other Tasks API endpoints. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.tasks().createTask( + TaskCreation + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**taskId:** `Optional` + +If non-empty, will set the requested Task ID, otherwise will generate a new random +GUID. Will reject if supplied Task ID does not match [A-Za-z0-9_-.]{5,36}. + +
+
+ +
+
+ +**displayName:** `Optional` — Human readable display name for this Task, should be short (<100 chars). + +
+
+ +
+
+ +**description:** `Optional` — Longer, free form human readable description of this Task. + +
+
+ +
+
+ +**specification:** `Optional` — The path for the Protobuf task definition, and the complete task data. + +
+
+ +
+
+ +**author:** `Optional` + +
+
+ +
+
+ +**relations:** `Optional` + +Any relationships associated with this Task, such as a parent Task or an assignee +this Task is designated to for execution. + +
+
+ +
+
+ +**isExecutedElsewhere:** `Optional` + +If set, then the service will not trigger execution of this task on an agent. Useful +for when ingesting tasks from an external system that is triggering execution of tasks +on agents. + +
+
+ +
+
+ +**initialEntities:** `Optional>` + +Indicates an initial set of entities that can be used to execute an entity aware +task. For example, an entity Objective, an entity Keep In Zone, etc. + +
+
+
+
+ + +
+
+
+ +
client.tasks.getTask(taskId) -> Task +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a specific Task by its ID, with options to select a particular task version or view. + +This method returns detailed information about a task including its current status, +specification, relations, and other metadata. The response includes the complete Task object +with all associated fields. + +By default, the method returns the latest definition version of the task from the manager's +perspective. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.tasks().getTask( + "taskId", + GetTaskRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**taskId:** `String` — ID of task to return + +
+
+
+
+ + +
+
+
+ +
client.tasks.updateTaskStatus(taskId, request) -> Task +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates the status of a Task as it progresses through its lifecycle. + +This method allows agents or operators to report the current state of a task, +which could include changes to task status, and error information. + +Each status update increments the task's status_version. When updating status, +clients must provide the current version to ensure consistency. The system rejects +updates with mismatched versions to prevent race conditions. + +Terminal states (`STATUS_DONE_OK` and `STATUS_DONE_NOT_OK`) are permanent; once a task +reaches these states, no further updates are allowed. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.tasks().updateTaskStatus( + "taskId", + TaskStatusUpdate + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**taskId:** `String` — ID of task to update status of + +
+
+ +
+
+ +**statusVersion:** `Optional` + +The status version of the task to update. This version number increments to indicate the task's +current stage in its status lifecycle. Specifically, whenever a task's status updates, the status +version increments by one. Any status updates received with a lower status version number than what +is known are considered stale and ignored. + +
+
+ +
+
+ +**newStatus:** `Optional` — The new status of the task. + +
+
+ +
+
+ +**author:** `Optional` + +
+
+
+
+ + +
+
+
+ +
client.tasks.queryTasks(request) -> TaskQueryResults +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Searches for Tasks that match specified filtering criteria and returns matching tasks in paginated form. + +This method allows filtering tasks based on multiple criteria including: +- Parent task relationships +- Task status (with inclusive or exclusive filtering) +- Update time ranges +- Task view (manager or agent perspective) +- Task assignee +- Task type (via exact URL matches or prefix matching) + +Results are returned in pages. When more results are available than can be returned in a single +response, a page_token is provided that can be used in subsequent requests to retrieve the next +set of results. + +By default, this returns the latest task version for each matching task from the manager's perspective. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.tasks().queryTasks( + TaskQuery + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**pageToken:** `Optional` — If set, returns results starting from the given pageToken. + +
+
+ +
+
+ +**parentTaskId:** `Optional` + +If present matches Tasks with this parent Task ID. +Note: this is mutually exclusive with all other query parameters, for example, either provide parent task ID, or +any of the remaining parameters, but not both. + +
+
+ +
+
+ +**statusFilter:** `Optional` + +
+
+ +
+
+ +**updateTimeRange:** `Optional` — If provided, only provides Tasks updated within the time range. + +
+
+
+
+ + +
+
+
+ +
client.tasks.listenAsAgent(request) -> AgentRequest +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Establishes a server streaming connection that delivers tasks to taskable agents for execution. + +This method creates a persistent connection from Tasks API to an agent, allowing the server +to push tasks to the agent as they become available. The agent receives a stream of tasks that +match its selector criteria (entity IDs). + +The stream delivers three types of requests: +- ExecuteRequest: Contains a new task for the agent to execute +- CancelRequest: Indicates a task should be canceled +- CompleteRequest: Indicates a task should be completed + +This is the primary method for taskable agents to receive and process tasks in real-time. +Agents should maintain this connection and process incoming tasks according to their capabilities. + +When an agent receives a task, it should update the task status using the UpdateStatus endpoint +to provide progress information back to Tasks API. + +This is a long polling API that will block until a new task is ready for delivery. If no new task is +available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout +period you will be expected to reinitiate a new request. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.tasks().listenAsAgent( + AgentListener + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agentSelector:** `Optional` — Selector criteria to determine which Agent Tasks the agent receives + +
+
+
+
+ + +
+
+
+ +
client.tasks.listenAsAgentStream(request) -> Optional<ListenAsAgentStreamResponse> +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Establishes a server streaming connection that delivers tasks to taskable agents for execution +using Server-Sent Events (SSE). + +This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria. + +The stream delivers three types of requests: +- `ExecuteRequest`: Contains a new task for the agent to execute +- `CancelRequest`: Indicates a task should be canceled +- `CompleteRequest`: Indicates a task should be completed + +Additionally, heartbeat messages are sent periodically to maintain the connection. + +This is recommended method for taskable agents to receive and process tasks in real-time. +Agents should maintain connection to this stream and process incoming tasks according to their capabilities. + +When an agent receives a task, it should update the task status using the `UpdateStatus` endpoint +to provide progress information back to Tasks API. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.tasks().listenAsAgentStream( + AgentStreamRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**agentSelector:** `Optional` — The selector criteria to determine which tasks the agent receives. + +
+
+ +
+
+ +**heartbeatIntervalMs:** `Optional` — The time interval, defined in seconds, that determines the frequency at which to send heartbeat events. Defaults to 30s. + +
+
+
+
+ + +
+
+
+ +## Objects +
client.objects.listObjects() -> SyncPagingIterable<PathMetadata> +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Lists objects in your environment. You can define a prefix to list a subset of your objects. If you do not set a prefix, Lattice returns all available objects. By default this endpoint will list local objects only. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.objects().listObjects( + ListObjectsRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**prefix:** `Optional` — Filters the objects based on the specified prefix path. If no path is specified, all objects are returned. + +
+
+ +
+
+ +**sinceTimestamp:** `Optional` — Sets the age for the oldest objects to query across the environment. + +
+
+ +
+
+ +**pageToken:** `Optional` — Base64 and URL-encoded cursor returned by the service to continue paging. + +
+
+ +
+
+ +**allObjectsInMesh:** `Optional` — Lists objects across all environment nodes in a Lattice Mesh. + +
+
+
+
+ + +
+
+
+ +
client.objects.getObject(objectPath) -> InputStream +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Fetches an object from your environment using the objectPath path parameter. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.objects().getObject( + "objectPath", + GetObjectRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**objectPath:** `String` — The path of the object to fetch. + +
+
+ +
+
+ +**acceptEncoding:** `Optional` — If set, Lattice will compress the response using the specified compression method. If the header is not defined, or the compression method is set to `identity`, no compression will be applied to the response. + +
+
+ +
+
+ +**priority:** `Optional` — Indicates a client's preference for the priority of the response. The value is a structured header as defined in RFC 9218. If you do not set the header, Lattice uses the default priority set for the environment. Incremental delivery directives are not supported and will be ignored. + +
+
+
+
+ + +
+
+
+ +
client.objects.uploadObject(objectPath, request) -> PathMetadata +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Uploads an object. The object must be 1 GiB or smaller. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.objects().uploadObject("".getBytes()); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**objectPath:** `String` — Path of the Object that is to be uploaded. + +
+
+
+
+ + +
+
+
+ +
client.objects.deleteObject(objectPath) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes an object from your environment given the objectPath path parameter. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.objects().deleteObject( + "objectPath", + DeleteObjectRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**objectPath:** `String` — The path of the object to delete. + +
+
+
+
+ + +
+
+
+ +
client.objects.getObjectMetadata(objectPath) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns metadata for a specified object path. Use this to fetch metadata such as object size (size_bytes), its expiry time (expiry_time), or its latest update timestamp (last_updated_at). +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```java +client.objects().getObjectMetadata( + "objectPath", + GetObjectMetadataRequest + .builder() + .build() +); +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**objectPath:** `String` — The path of the object to query. + +
+
+
+
+ + +
+
+
diff --git a/src/main/java/com/anduril/core/ClientOptions.java b/src/main/java/com/anduril/core/ClientOptions.java index 5cd368c..f0b6d45 100644 --- a/src/main/java/com/anduril/core/ClientOptions.java +++ b/src/main/java/com/anduril/core/ClientOptions.java @@ -35,10 +35,10 @@ private ClientOptions( this.headers.putAll(headers); this.headers.putAll(new HashMap() { { - put("User-Agent", "com.anduril:lattice-sdk/5.0.0"); + put("User-Agent", "com.anduril:lattice-sdk/5.1.0"); put("X-Fern-Language", "JAVA"); put("X-Fern-SDK-Name", "com.anduril.fern:api-sdk"); - put("X-Fern-SDK-Version", "5.0.0"); + put("X-Fern-SDK-Version", "5.1.0"); } }); this.headerSuppliers = headerSuppliers; diff --git a/src/main/java/com/anduril/resources/tasks/AsyncRawTasksClient.java b/src/main/java/com/anduril/resources/tasks/AsyncRawTasksClient.java index 29b2190..2155b7d 100644 --- a/src/main/java/com/anduril/resources/tasks/AsyncRawTasksClient.java +++ b/src/main/java/com/anduril/resources/tasks/AsyncRawTasksClient.java @@ -10,14 +10,18 @@ import com.anduril.core.MediaTypes; import com.anduril.core.ObjectMappers; import com.anduril.core.RequestOptions; +import com.anduril.core.ResponseBodyReader; +import com.anduril.core.Stream; import com.anduril.errors.BadRequestError; import com.anduril.errors.NotFoundError; import com.anduril.errors.UnauthorizedError; import com.anduril.resources.tasks.requests.AgentListener; +import com.anduril.resources.tasks.requests.AgentStreamRequest; import com.anduril.resources.tasks.requests.GetTaskRequest; import com.anduril.resources.tasks.requests.TaskCreation; import com.anduril.resources.tasks.requests.TaskQuery; import com.anduril.resources.tasks.requests.TaskStatusUpdate; +import com.anduril.resources.tasks.types.ListenAsAgentStreamResponse; import com.anduril.types.AgentRequest; import com.anduril.types.Task; import com.anduril.types.TaskQueryResults; @@ -615,4 +619,132 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) { }); return future; } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ * + *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public CompletableFuture>> listenAsAgentStream() { + return listenAsAgentStream(AgentStreamRequest.builder().build()); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ * + *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public CompletableFuture>> listenAsAgentStream( + AgentStreamRequest request) { + return listenAsAgentStream(request, null); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public CompletableFuture>> listenAsAgentStream( + AgentStreamRequest request, RequestOptions requestOptions) { + HttpUrl httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) + .newBuilder() + .addPathSegments("api/v1/agent/stream") + .build(); + RequestBody body; + try { + body = RequestBody.create( + ObjectMappers.JSON_MAPPER.writeValueAsBytes(request), MediaTypes.APPLICATION_JSON); + } catch (JsonProcessingException e) { + throw new LatticeException("Failed to serialize request", e); + } + Request okhttpRequest = new Request.Builder() + .url(httpUrl) + .method("POST", body) + .headers(Headers.of(clientOptions.headers(requestOptions))) + .addHeader("Content-Type", "application/json") + .addHeader("Accept", "application/json") + .build(); + OkHttpClient client = clientOptions.httpClient(); + if (requestOptions != null && requestOptions.getTimeout().isPresent()) { + client = clientOptions.httpClientWithTimeout(requestOptions); + } + CompletableFuture>> future = + new CompletableFuture<>(); + client.newCall(okhttpRequest).enqueue(new Callback() { + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + try { + ResponseBody responseBody = response.body(); + if (response.isSuccessful()) { + future.complete(new LatticeHttpResponse<>( + Stream.fromSse(ListenAsAgentStreamResponse.class, new ResponseBodyReader(response)), + response)); + return; + } + String responseBodyString = responseBody != null ? responseBody.string() : "{}"; + try { + switch (response.code()) { + case 400: + future.completeExceptionally(new BadRequestError( + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); + return; + case 401: + future.completeExceptionally(new UnauthorizedError( + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), + response)); + return; + } + } catch (JsonProcessingException ignored) { + // unable to map error response, throwing generic error + } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); + future.completeExceptionally(new LatticeApiException( + "Error with status code " + response.code(), response.code(), errorBody, response)); + return; + } catch (IOException e) { + future.completeExceptionally(new LatticeException("Network error executing HTTP request", e)); + } + } + + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + future.completeExceptionally(new LatticeException("Network error executing HTTP request", e)); + } + }); + return future; + } } diff --git a/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java b/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java index 075a5c2..2eb6553 100644 --- a/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java +++ b/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java @@ -6,10 +6,12 @@ import com.anduril.core.ClientOptions; import com.anduril.core.RequestOptions; import com.anduril.resources.tasks.requests.AgentListener; +import com.anduril.resources.tasks.requests.AgentStreamRequest; import com.anduril.resources.tasks.requests.GetTaskRequest; import com.anduril.resources.tasks.requests.TaskCreation; import com.anduril.resources.tasks.requests.TaskQuery; import com.anduril.resources.tasks.requests.TaskStatusUpdate; +import com.anduril.resources.tasks.types.ListenAsAgentStreamResponse; import com.anduril.types.AgentRequest; import com.anduril.types.Task; import com.anduril.types.TaskQueryResults; @@ -275,4 +277,65 @@ public CompletableFuture listenAsAgent(AgentListener request) { public CompletableFuture listenAsAgent(AgentListener request, RequestOptions requestOptions) { return this.rawClient.listenAsAgent(request, requestOptions).thenApply(response -> response.body()); } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public CompletableFuture> listenAsAgentStream() { + return this.rawClient.listenAsAgentStream().thenApply(response -> response.body()); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public CompletableFuture> listenAsAgentStream(AgentStreamRequest request) { + return this.rawClient.listenAsAgentStream(request).thenApply(response -> response.body()); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public CompletableFuture> listenAsAgentStream( + AgentStreamRequest request, RequestOptions requestOptions) { + return this.rawClient.listenAsAgentStream(request, requestOptions).thenApply(response -> response.body()); + } } diff --git a/src/main/java/com/anduril/resources/tasks/RawTasksClient.java b/src/main/java/com/anduril/resources/tasks/RawTasksClient.java index 26e6f98..fe0a449 100644 --- a/src/main/java/com/anduril/resources/tasks/RawTasksClient.java +++ b/src/main/java/com/anduril/resources/tasks/RawTasksClient.java @@ -10,14 +10,18 @@ import com.anduril.core.MediaTypes; import com.anduril.core.ObjectMappers; import com.anduril.core.RequestOptions; +import com.anduril.core.ResponseBodyReader; +import com.anduril.core.Stream; import com.anduril.errors.BadRequestError; import com.anduril.errors.NotFoundError; import com.anduril.errors.UnauthorizedError; import com.anduril.resources.tasks.requests.AgentListener; +import com.anduril.resources.tasks.requests.AgentStreamRequest; import com.anduril.resources.tasks.requests.GetTaskRequest; import com.anduril.resources.tasks.requests.TaskCreation; import com.anduril.resources.tasks.requests.TaskQuery; import com.anduril.resources.tasks.requests.TaskStatusUpdate; +import com.anduril.resources.tasks.types.ListenAsAgentStreamResponse; import com.anduril.types.AgentRequest; import com.anduril.types.Task; import com.anduril.types.TaskQueryResults; @@ -515,4 +519,112 @@ public LatticeHttpResponse listenAsAgent(AgentListener request, Re throw new LatticeException("Network error executing HTTP request", e); } } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public LatticeHttpResponse> listenAsAgentStream() { + return listenAsAgentStream(AgentStreamRequest.builder().build()); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public LatticeHttpResponse> listenAsAgentStream(AgentStreamRequest request) { + return listenAsAgentStream(request, null); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public LatticeHttpResponse> listenAsAgentStream( + AgentStreamRequest request, RequestOptions requestOptions) { + HttpUrl httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl()) + .newBuilder() + .addPathSegments("api/v1/agent/stream") + .build(); + RequestBody body; + try { + body = RequestBody.create( + ObjectMappers.JSON_MAPPER.writeValueAsBytes(request), MediaTypes.APPLICATION_JSON); + } catch (JsonProcessingException e) { + throw new LatticeException("Failed to serialize request", e); + } + Request okhttpRequest = new Request.Builder() + .url(httpUrl) + .method("POST", body) + .headers(Headers.of(clientOptions.headers(requestOptions))) + .addHeader("Content-Type", "application/json") + .addHeader("Accept", "application/json") + .build(); + OkHttpClient client = clientOptions.httpClient(); + if (requestOptions != null && requestOptions.getTimeout().isPresent()) { + client = clientOptions.httpClientWithTimeout(requestOptions); + } + try { + Response response = client.newCall(okhttpRequest).execute(); + ResponseBody responseBody = response.body(); + if (response.isSuccessful()) { + return new LatticeHttpResponse<>( + Stream.fromSse(ListenAsAgentStreamResponse.class, new ResponseBodyReader(response)), response); + } + String responseBodyString = responseBody != null ? responseBody.string() : "{}"; + try { + switch (response.code()) { + case 400: + throw new BadRequestError( + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response); + case 401: + throw new UnauthorizedError( + ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response); + } + } catch (JsonProcessingException ignored) { + // unable to map error response, throwing generic error + } + Object errorBody = ObjectMappers.parseErrorBody(responseBodyString); + throw new LatticeApiException( + "Error with status code " + response.code(), response.code(), errorBody, response); + } catch (IOException e) { + throw new LatticeException("Network error executing HTTP request", e); + } + } } diff --git a/src/main/java/com/anduril/resources/tasks/TasksClient.java b/src/main/java/com/anduril/resources/tasks/TasksClient.java index bbfa2e2..9c76d4f 100644 --- a/src/main/java/com/anduril/resources/tasks/TasksClient.java +++ b/src/main/java/com/anduril/resources/tasks/TasksClient.java @@ -6,10 +6,12 @@ import com.anduril.core.ClientOptions; import com.anduril.core.RequestOptions; import com.anduril.resources.tasks.requests.AgentListener; +import com.anduril.resources.tasks.requests.AgentStreamRequest; import com.anduril.resources.tasks.requests.GetTaskRequest; import com.anduril.resources.tasks.requests.TaskCreation; import com.anduril.resources.tasks.requests.TaskQuery; import com.anduril.resources.tasks.requests.TaskStatusUpdate; +import com.anduril.resources.tasks.types.ListenAsAgentStreamResponse; import com.anduril.types.AgentRequest; import com.anduril.types.Task; import com.anduril.types.TaskQueryResults; @@ -273,4 +275,65 @@ public AgentRequest listenAsAgent(AgentListener request) { public AgentRequest listenAsAgent(AgentListener request, RequestOptions requestOptions) { return this.rawClient.listenAsAgent(request, requestOptions).body(); } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public Iterable listenAsAgentStream() { + return this.rawClient.listenAsAgentStream().body(); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public Iterable listenAsAgentStream(AgentStreamRequest request) { + return this.rawClient.listenAsAgentStream(request).body(); + } + + /** + * Establishes a server streaming connection that delivers tasks to taskable agents for execution + * using Server-Sent Events (SSE). + *

This method creates a connection from the Tasks API to an agent that streams relevant tasks to the listener agent. The agent receives a stream of tasks that match the entities specified by the tasks' selector criteria.

+ *

The stream delivers three types of requests:

+ *
    + *
  • ExecuteRequest: Contains a new task for the agent to execute
  • + *
  • CancelRequest: Indicates a task should be canceled
  • + *
  • CompleteRequest: Indicates a task should be completed
  • + *
+ *

Additionally, heartbeat messages are sent periodically to maintain the connection.

+ *

This is recommended method for taskable agents to receive and process tasks in real-time. + * Agents should maintain connection to this stream and process incoming tasks according to their capabilities.

+ *

When an agent receives a task, it should update the task status using the UpdateStatus endpoint + * to provide progress information back to Tasks API.

+ */ + public Iterable listenAsAgentStream( + AgentStreamRequest request, RequestOptions requestOptions) { + return this.rawClient.listenAsAgentStream(request, requestOptions).body(); + } } diff --git a/src/main/java/com/anduril/resources/tasks/requests/AgentStreamRequest.java b/src/main/java/com/anduril/resources/tasks/requests/AgentStreamRequest.java new file mode 100644 index 0000000..69c1e8f --- /dev/null +++ b/src/main/java/com/anduril/resources/tasks/requests/AgentStreamRequest.java @@ -0,0 +1,133 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.anduril.resources.tasks.requests; + +import com.anduril.core.ObjectMappers; +import com.anduril.types.EntityIdsSelector; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentStreamRequest.Builder.class) +public final class AgentStreamRequest { + private final Optional agentSelector; + + private final Optional heartbeatIntervalMs; + + private final Map additionalProperties; + + private AgentStreamRequest( + Optional agentSelector, + Optional heartbeatIntervalMs, + Map additionalProperties) { + this.agentSelector = agentSelector; + this.heartbeatIntervalMs = heartbeatIntervalMs; + this.additionalProperties = additionalProperties; + } + + /** + * @return The selector criteria to determine which tasks the agent receives. + */ + @JsonProperty("agentSelector") + public Optional getAgentSelector() { + return agentSelector; + } + + /** + * @return The time interval, defined in seconds, that determines the frequency at which to send heartbeat events. Defaults to 30s. + */ + @JsonProperty("heartbeatIntervalMs") + public Optional getHeartbeatIntervalMs() { + return heartbeatIntervalMs; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentStreamRequest && equalTo((AgentStreamRequest) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentStreamRequest other) { + return agentSelector.equals(other.agentSelector) && heartbeatIntervalMs.equals(other.heartbeatIntervalMs); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.agentSelector, this.heartbeatIntervalMs); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional agentSelector = Optional.empty(); + + private Optional heartbeatIntervalMs = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentStreamRequest other) { + agentSelector(other.getAgentSelector()); + heartbeatIntervalMs(other.getHeartbeatIntervalMs()); + return this; + } + + /** + *

The selector criteria to determine which tasks the agent receives.

+ */ + @JsonSetter(value = "agentSelector", nulls = Nulls.SKIP) + public Builder agentSelector(Optional agentSelector) { + this.agentSelector = agentSelector; + return this; + } + + public Builder agentSelector(EntityIdsSelector agentSelector) { + this.agentSelector = Optional.ofNullable(agentSelector); + return this; + } + + /** + *

The time interval, defined in seconds, that determines the frequency at which to send heartbeat events. Defaults to 30s.

+ */ + @JsonSetter(value = "heartbeatIntervalMs", nulls = Nulls.SKIP) + public Builder heartbeatIntervalMs(Optional heartbeatIntervalMs) { + this.heartbeatIntervalMs = heartbeatIntervalMs; + return this; + } + + public Builder heartbeatIntervalMs(Integer heartbeatIntervalMs) { + this.heartbeatIntervalMs = Optional.ofNullable(heartbeatIntervalMs); + return this; + } + + public AgentStreamRequest build() { + return new AgentStreamRequest(agentSelector, heartbeatIntervalMs, additionalProperties); + } + } +} diff --git a/src/main/java/com/anduril/resources/tasks/types/ListenAsAgentStreamResponse.java b/src/main/java/com/anduril/resources/tasks/types/ListenAsAgentStreamResponse.java new file mode 100644 index 0000000..f3a41f2 --- /dev/null +++ b/src/main/java/com/anduril/resources/tasks/types/ListenAsAgentStreamResponse.java @@ -0,0 +1,205 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.anduril.resources.tasks.types; + +import com.anduril.types.AgentStreamEvent; +import com.anduril.types.AgentStreamHeartbeat; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Objects; +import java.util.Optional; + +public final class ListenAsAgentStreamResponse { + private final Value value; + + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + private ListenAsAgentStreamResponse(Value value) { + this.value = value; + } + + public T visit(Visitor visitor) { + return value.visit(visitor); + } + + public static ListenAsAgentStreamResponse heartbeat(AgentStreamHeartbeat value) { + return new ListenAsAgentStreamResponse(new HeartbeatValue(value)); + } + + public static ListenAsAgentStreamResponse agentRequest(AgentStreamEvent value) { + return new ListenAsAgentStreamResponse(new AgentRequestValue(value)); + } + + public boolean isHeartbeat() { + return value instanceof HeartbeatValue; + } + + public boolean isAgentRequest() { + return value instanceof AgentRequestValue; + } + + public boolean _isUnknown() { + return value instanceof _UnknownValue; + } + + public Optional getHeartbeat() { + if (isHeartbeat()) { + return Optional.of(((HeartbeatValue) value).value); + } + return Optional.empty(); + } + + public Optional getAgentRequest() { + if (isAgentRequest()) { + return Optional.of(((AgentRequestValue) value).value); + } + return Optional.empty(); + } + + public Optional _getUnknown() { + if (_isUnknown()) { + return Optional.of(((_UnknownValue) value).value); + } + return Optional.empty(); + } + + @JsonValue + private Value getValue() { + return this.value; + } + + public interface Visitor { + T visitHeartbeat(AgentStreamHeartbeat heartbeat); + + T visitAgentRequest(AgentStreamEvent agentRequest); + + T _visitUnknown(Object unknownType); + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "event", visible = true, defaultImpl = _UnknownValue.class) + @JsonSubTypes({@JsonSubTypes.Type(HeartbeatValue.class), @JsonSubTypes.Type(AgentRequestValue.class)}) + @JsonIgnoreProperties(ignoreUnknown = true) + private interface Value { + T visit(Visitor visitor); + } + + @JsonTypeName("heartbeat") + @JsonIgnoreProperties("event") + private static final class HeartbeatValue implements Value { + @JsonUnwrapped + private AgentStreamHeartbeat value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private HeartbeatValue() {} + + private HeartbeatValue(AgentStreamHeartbeat value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitHeartbeat(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof HeartbeatValue && equalTo((HeartbeatValue) other); + } + + private boolean equalTo(HeartbeatValue other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "ListenAsAgentStreamResponse{" + "value: " + value + "}"; + } + } + + @JsonTypeName("agent_request") + @JsonIgnoreProperties("event") + private static final class AgentRequestValue implements Value { + @JsonUnwrapped + private AgentStreamEvent value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private AgentRequestValue() {} + + private AgentRequestValue(AgentStreamEvent value) { + this.value = value; + } + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor.visitAgentRequest(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentRequestValue && equalTo((AgentRequestValue) other); + } + + private boolean equalTo(AgentRequestValue other) { + return value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.value); + } + + @java.lang.Override + public String toString() { + return "ListenAsAgentStreamResponse{" + "value: " + value + "}"; + } + } + + @JsonIgnoreProperties("event") + private static final class _UnknownValue implements Value { + private String type; + + @JsonValue + private Object value; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + private _UnknownValue(@JsonProperty("value") Object value) {} + + @java.lang.Override + public T visit(Visitor visitor) { + return visitor._visitUnknown(value); + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof _UnknownValue && equalTo((_UnknownValue) other); + } + + private boolean equalTo(_UnknownValue other) { + return type.equals(other.type) && value.equals(other.value); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.type, this.value); + } + + @java.lang.Override + public String toString() { + return "ListenAsAgentStreamResponse{" + "type: " + type + ", value: " + value + "}"; + } + } +} diff --git a/src/main/java/com/anduril/types/AgentStreamEvent.java b/src/main/java/com/anduril/types/AgentStreamEvent.java new file mode 100644 index 0000000..4c4ef73 --- /dev/null +++ b/src/main/java/com/anduril/types/AgentStreamEvent.java @@ -0,0 +1,102 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.anduril.types; + +import com.anduril.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.jetbrains.annotations.NotNull; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentStreamEvent.Builder.class) +public final class AgentStreamEvent { + private final AgentTaskRequest data; + + private final Map additionalProperties; + + private AgentStreamEvent(AgentTaskRequest data, Map additionalProperties) { + this.data = data; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("data") + public AgentTaskRequest getData() { + return data; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentStreamEvent && equalTo((AgentStreamEvent) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentStreamEvent other) { + return data.equals(other.data); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.data); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static DataStage builder() { + return new Builder(); + } + + public interface DataStage { + _FinalStage data(@NotNull AgentTaskRequest data); + + Builder from(AgentStreamEvent other); + } + + public interface _FinalStage { + AgentStreamEvent build(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder implements DataStage, _FinalStage { + private AgentTaskRequest data; + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + @java.lang.Override + public Builder from(AgentStreamEvent other) { + data(other.getData()); + return this; + } + + @java.lang.Override + @JsonSetter("data") + public _FinalStage data(@NotNull AgentTaskRequest data) { + this.data = Objects.requireNonNull(data, "data must not be null"); + return this; + } + + @java.lang.Override + public AgentStreamEvent build() { + return new AgentStreamEvent(data, additionalProperties); + } + } +} diff --git a/src/main/java/com/anduril/types/AgentStreamHeartbeat.java b/src/main/java/com/anduril/types/AgentStreamHeartbeat.java new file mode 100644 index 0000000..228d232 --- /dev/null +++ b/src/main/java/com/anduril/types/AgentStreamHeartbeat.java @@ -0,0 +1,102 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.anduril.types; + +import com.anduril.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.jetbrains.annotations.NotNull; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentStreamHeartbeat.Builder.class) +public final class AgentStreamHeartbeat { + private final AgentStreamHeartbeatData data; + + private final Map additionalProperties; + + private AgentStreamHeartbeat(AgentStreamHeartbeatData data, Map additionalProperties) { + this.data = data; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("data") + public AgentStreamHeartbeatData getData() { + return data; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentStreamHeartbeat && equalTo((AgentStreamHeartbeat) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentStreamHeartbeat other) { + return data.equals(other.data); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.data); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static DataStage builder() { + return new Builder(); + } + + public interface DataStage { + _FinalStage data(@NotNull AgentStreamHeartbeatData data); + + Builder from(AgentStreamHeartbeat other); + } + + public interface _FinalStage { + AgentStreamHeartbeat build(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder implements DataStage, _FinalStage { + private AgentStreamHeartbeatData data; + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + @java.lang.Override + public Builder from(AgentStreamHeartbeat other) { + data(other.getData()); + return this; + } + + @java.lang.Override + @JsonSetter("data") + public _FinalStage data(@NotNull AgentStreamHeartbeatData data) { + this.data = Objects.requireNonNull(data, "data must not be null"); + return this; + } + + @java.lang.Override + public AgentStreamHeartbeat build() { + return new AgentStreamHeartbeat(data, additionalProperties); + } + } +} diff --git a/src/main/java/com/anduril/types/AgentStreamHeartbeatData.java b/src/main/java/com/anduril/types/AgentStreamHeartbeatData.java new file mode 100644 index 0000000..a1671d3 --- /dev/null +++ b/src/main/java/com/anduril/types/AgentStreamHeartbeatData.java @@ -0,0 +1,101 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.anduril.types; + +import com.anduril.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentStreamHeartbeatData.Builder.class) +public final class AgentStreamHeartbeatData { + private final Optional timestamp; + + private final Map additionalProperties; + + private AgentStreamHeartbeatData(Optional timestamp, Map additionalProperties) { + this.timestamp = timestamp; + this.additionalProperties = additionalProperties; + } + + /** + * @return The timestamp at which the heartbeat message was sent. + */ + @JsonProperty("timestamp") + public Optional getTimestamp() { + return timestamp; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentStreamHeartbeatData && equalTo((AgentStreamHeartbeatData) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentStreamHeartbeatData other) { + return timestamp.equals(other.timestamp); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.timestamp); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional timestamp = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentStreamHeartbeatData other) { + timestamp(other.getTimestamp()); + return this; + } + + /** + *

The timestamp at which the heartbeat message was sent.

+ */ + @JsonSetter(value = "timestamp", nulls = Nulls.SKIP) + public Builder timestamp(Optional timestamp) { + this.timestamp = timestamp; + return this; + } + + public Builder timestamp(String timestamp) { + this.timestamp = Optional.ofNullable(timestamp); + return this; + } + + public AgentStreamHeartbeatData build() { + return new AgentStreamHeartbeatData(timestamp, additionalProperties); + } + } +} diff --git a/src/main/java/com/anduril/types/AgentTaskRequest.java b/src/main/java/com/anduril/types/AgentTaskRequest.java new file mode 100644 index 0000000..096fee8 --- /dev/null +++ b/src/main/java/com/anduril/types/AgentTaskRequest.java @@ -0,0 +1,145 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +package com.anduril.types; + +import com.anduril.core.ObjectMappers; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@JsonInclude(JsonInclude.Include.NON_ABSENT) +@JsonDeserialize(builder = AgentTaskRequest.Builder.class) +public final class AgentTaskRequest { + private final Optional executeRequest; + + private final Optional cancelRequest; + + private final Optional completeRequest; + + private final Map additionalProperties; + + private AgentTaskRequest( + Optional executeRequest, + Optional cancelRequest, + Optional completeRequest, + Map additionalProperties) { + this.executeRequest = executeRequest; + this.cancelRequest = cancelRequest; + this.completeRequest = completeRequest; + this.additionalProperties = additionalProperties; + } + + @JsonProperty("executeRequest") + public Optional getExecuteRequest() { + return executeRequest; + } + + @JsonProperty("cancelRequest") + public Optional getCancelRequest() { + return cancelRequest; + } + + @JsonProperty("completeRequest") + public Optional getCompleteRequest() { + return completeRequest; + } + + @java.lang.Override + public boolean equals(Object other) { + if (this == other) return true; + return other instanceof AgentTaskRequest && equalTo((AgentTaskRequest) other); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + private boolean equalTo(AgentTaskRequest other) { + return executeRequest.equals(other.executeRequest) + && cancelRequest.equals(other.cancelRequest) + && completeRequest.equals(other.completeRequest); + } + + @java.lang.Override + public int hashCode() { + return Objects.hash(this.executeRequest, this.cancelRequest, this.completeRequest); + } + + @java.lang.Override + public String toString() { + return ObjectMappers.stringify(this); + } + + public static Builder builder() { + return new Builder(); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class Builder { + private Optional executeRequest = Optional.empty(); + + private Optional cancelRequest = Optional.empty(); + + private Optional completeRequest = Optional.empty(); + + @JsonAnySetter + private Map additionalProperties = new HashMap<>(); + + private Builder() {} + + public Builder from(AgentTaskRequest other) { + executeRequest(other.getExecuteRequest()); + cancelRequest(other.getCancelRequest()); + completeRequest(other.getCompleteRequest()); + return this; + } + + @JsonSetter(value = "executeRequest", nulls = Nulls.SKIP) + public Builder executeRequest(Optional executeRequest) { + this.executeRequest = executeRequest; + return this; + } + + public Builder executeRequest(ExecuteRequest executeRequest) { + this.executeRequest = Optional.ofNullable(executeRequest); + return this; + } + + @JsonSetter(value = "cancelRequest", nulls = Nulls.SKIP) + public Builder cancelRequest(Optional cancelRequest) { + this.cancelRequest = cancelRequest; + return this; + } + + public Builder cancelRequest(CancelRequest cancelRequest) { + this.cancelRequest = Optional.ofNullable(cancelRequest); + return this; + } + + @JsonSetter(value = "completeRequest", nulls = Nulls.SKIP) + public Builder completeRequest(Optional completeRequest) { + this.completeRequest = completeRequest; + return this; + } + + public Builder completeRequest(CompleteRequest completeRequest) { + this.completeRequest = Optional.ofNullable(completeRequest); + return this; + } + + public AgentTaskRequest build() { + return new AgentTaskRequest(executeRequest, cancelRequest, completeRequest, additionalProperties); + } + } +}