Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ For Spring Boot applications, use the starter dependency for zero-configuration
<dependency>
<groupId>ai.gradientlabs</groupId>
<artifactId>gradient-labs-spring-boot-starter</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
</dependency>
```

### Gradle

```gradle
implementation 'ai.gradientlabs:gradient-labs-spring-boot-starter:1.0.0'
implementation 'ai.gradientlabs:gradient-labs-spring-boot-starter:1.1.0'
```

### Configuration
Expand Down Expand Up @@ -95,14 +95,14 @@ For non-Spring applications, use the core client library:
<dependency>
<groupId>ai.gradientlabs</groupId>
<artifactId>gradient-labs-client</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
</dependency>
```

### Gradle

```gradle
implementation 'ai.gradientlabs:gradient-labs-client:1.0.0'
implementation 'ai.gradientlabs:gradient-labs-client:1.1.0'
```

## Error Handling
Expand Down
2 changes: 1 addition & 1 deletion gradient-labs-client/examples/spring-boot-example/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<dependency>
<groupId>ai.gradientlabs</groupId>
<artifactId>gradient-labs-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.1.0</version>
</dependency>

<!-- Spring Boot Web -->
Expand Down
16 changes: 15 additions & 1 deletion gradient-labs-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>ai.gradientlabs</groupId>
<artifactId>gradient-labs-parent</artifactId>
<version>1.0.1-SNAPSHOT</version>
<version>1.1.0</version>
</parent>

<artifactId>gradient-labs-client</artifactId>
Expand Down Expand Up @@ -72,6 +72,20 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<!-- Implementation-Version in the manifest is what the User-Agent reports;
without it the client identifies itself as "dev". -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ai.gradientlabs.client.internal.HttpClientWrapper;
import ai.gradientlabs.client.model.*;
import ai.gradientlabs.client.request.*;
import ai.gradientlabs.client.response.StartOutboundConversationResponse;
import ai.gradientlabs.client.webhook.Webhook;
import ai.gradientlabs.client.webhook.WebhookVerifier;

Expand Down Expand Up @@ -80,24 +81,68 @@ public Conversation startConversation(StartConversationRequest request) {
}

/**
* Starts an outbound conversation.
* Starts an outbound live chat conversation.
* <p>
* Creates and starts a new outbound conversation where the AI agent proactively
* initiates contact with a customer. The conversation follows the instructions
* defined in the specified outbound procedure.
* Creates and starts a new outbound live chat conversation in which the AI agent
* proactively initiates contact with a customer, following the instructions defined in
* the specified outbound procedure.
* <p>
* If support_platform is not provided, the system will automatically select the
* highest priority platform that has integration settings configured for your company.
* If a body is provided, that message will be sent as the opening message. Otherwise,
* the AI agent will generate one based on the procedure.
* <p>
* If body and subject are provided, that message will be sent as the initial message.
* Otherwise, the AI agent will generate an appropriate initial message based on the procedure.
* The customer is created, or matched to an existing record, from the customer ID and
* any customer support platform identifiers you supply. The platform the chat is
* delivered on needs an identifier for that customer.
*
* @param request the outbound conversation parameters
* @param request the outbound chat conversation parameters
* @return the response containing the conversation ID
* @throws GradientLabsException if the request fails
*/
public ai.gradientlabs.client.response.StartOutboundConversationResponse startOutboundConversation(StartOutboundConversationRequest request) {
return httpClient.post("/outbound/conversations", request, ai.gradientlabs.client.response.StartOutboundConversationResponse.class);
public StartOutboundConversationResponse startOutboundChatConversation(StartOutboundChatConversationRequest request) {
return httpClient.post("/outbound/conversations/chat", request, StartOutboundConversationResponse.class);
}

/**
* Starts an outbound email conversation.
* <p>
* Creates and starts a new outbound email conversation in which the AI agent
* proactively initiates contact with a customer, following the instructions defined in
* the specified outbound procedure.
* <p>
* If a subject and body are provided, that email will be sent as the opening message.
* Otherwise, the AI agent will write one based on the procedure.
* <p>
* The customer is created, or matched to an existing record, from the customer ID and
* any customer support platform identifiers you supply. The platform the email is sent
* from needs an identifier for that customer, so sending from Zendesk needs a Zendesk
* identifier, and so on.
*
* @param request the outbound email conversation parameters
* @return the response containing the conversation ID
* @throws GradientLabsException if the request fails
*/
public StartOutboundConversationResponse startOutboundEmailConversation(StartOutboundEmailConversationRequest request) {
return httpClient.post("/outbound/conversations/email", request, StartOutboundConversationResponse.class);
}

/**
* Places an outbound phone call.
* <p>
* Places an outbound phone call in which the AI agent proactively contacts a customer,
* following the instructions defined in the specified outbound procedure.
* <p>
* The number the call is placed from must already be provisioned for your company.
* <p>
* The customer is created, or matched to an existing record, from the customer ID and
* any customer support platform identifiers you supply. The dialled number is recorded
* against that same customer.
*
* @param request the outbound phone conversation parameters
* @return the response containing the conversation ID
* @throws GradientLabsException if the request fails
*/
public StartOutboundConversationResponse startOutboundPhoneConversation(StartOutboundPhoneConversationRequest request) {
return httpClient.post("/outbound/conversations/phone", request, StartOutboundConversationResponse.class);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package ai.gradientlabs.client.request;

import ai.gradientlabs.client.model.CustomerSupportPlatformIdentifier;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Parameters for starting an outbound live chat conversation.
* <p>
* This kicks off a proactive conversation where your AI agent initiates contact with a
* customer over chat.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class StartOutboundChatConversationRequest {

@JsonProperty("customer_id")
private final String customerId;

@JsonProperty("customer_support_platform_identifiers")
private final List<CustomerSupportPlatformIdentifier> customerSupportPlatformIdentifiers;

@JsonProperty("procedure_id")
private final String procedureId;

@JsonProperty("support_platform")
private final String supportPlatform;

@JsonProperty("body")
private final String body;

@JsonProperty("resources")
private final Map<String, Object> resources;

private StartOutboundChatConversationRequest(Builder builder) {
this.customerId = builder.customerId;
this.customerSupportPlatformIdentifiers = builder.customerSupportPlatformIdentifiers;
this.procedureId = builder.procedureId;
this.supportPlatform = builder.supportPlatform;
this.body = builder.body;
this.resources = builder.resources;
}

public static Builder builder() {
return new Builder();
}

public String getCustomerId() {
return customerId;
}

public List<CustomerSupportPlatformIdentifier> getCustomerSupportPlatformIdentifiers() {
return customerSupportPlatformIdentifiers;
}

public String getProcedureId() {
return procedureId;
}

public String getSupportPlatform() {
return supportPlatform;
}

public String getBody() {
return body;
}

public Map<String, Object> getResources() {
return resources;
}

/**
* The support platforms an outbound chat can be delivered on.
*/
public static class SupportPlatform {
public static final String INTERCOM = "intercom";

/**
* Delivers the conversation to your own webhook endpoint.
*/
public static final String PUBLIC_API = "public-api";
}

public static class Builder {
private String customerId;
private List<CustomerSupportPlatformIdentifier> customerSupportPlatformIdentifiers;
private String procedureId;
private String supportPlatform;
private String body;
private Map<String, Object> resources;

private Builder() {
}

/**
* Sets your own identifier for the customer, as used in your systems (required).
* <p>
* It is stored as the customer's company customer ID, and is the identifier echoed
* back to you in tool and webhook payloads.
*
* @param customerId the customer ID
* @return this builder
*/
public Builder customerId(String customerId) {
this.customerId = customerId;
return this;
}

/**
* Sets the customer's identifiers in third-party customer support platforms (optional).
* <p>
* These are added to the customer alongside {@code customerId}, and can be used to
* match against customers created via those platforms' native integrations. The
* platform named in {@code supportPlatform} needs an identifier here, unless the
* customer already carries one from an earlier conversation.
*
* @param customerSupportPlatformIdentifiers the customer support platform identifiers
* @return this builder
*/
public Builder customerSupportPlatformIdentifiers(List<CustomerSupportPlatformIdentifier> customerSupportPlatformIdentifiers) {
this.customerSupportPlatformIdentifiers = customerSupportPlatformIdentifiers;
return this;
}

/**
* Adds a single customer support platform identifier.
*
* @param customerSupportPlatformIdentifier the identifier to add
* @return this builder
*/
public Builder addCustomerSupportPlatformIdentifier(CustomerSupportPlatformIdentifier customerSupportPlatformIdentifier) {
if (this.customerSupportPlatformIdentifiers == null) {
this.customerSupportPlatformIdentifiers = new ArrayList<>();
}
this.customerSupportPlatformIdentifiers.add(customerSupportPlatformIdentifier);
return this;
}

/**
* Sets the procedure ID (required).
* <p>
* The ID of the outbound procedure that defines what the AI agent should accomplish
* in this conversation. The procedure must be of type "outbound", must be live
* (deployed), and must be enabled for the chat channel.
*
* @param procedureId the procedure ID
* @return this builder
*/
public Builder procedureId(String procedureId) {
this.procedureId = procedureId;
return this;
}

/**
* Sets the support platform the chat is delivered on (required).
* <p>
* Use constants from {@link SupportPlatform}.
*
* @param supportPlatform the support platform
* @return this builder
*/
public Builder supportPlatform(String supportPlatform) {
this.supportPlatform = supportPlatform;
return this;
}

/**
* Sets the content of the initial message to send to the customer (optional).
* <p>
* If omitted, the AI agent will generate an appropriate opening message based on the
* procedure.
*
* @param body the body
* @return this builder
*/
public Builder body(String body) {
this.body = body;
return this;
}

/**
* Sets resources (optional).
* <p>
* A JSON object containing structured data that the AI agent can use during the
* conversation. This should be organized as a map where keys are resource type names
* and values are the corresponding data.
* Example: {"customer_profile": {"tier": "premium", "lifetime_value": 5000}}
*
* @param resources the resources
* @return this builder
*/
public Builder resources(Map<String, Object> resources) {
this.resources = resources;
return this;
}

/**
* Builds the request.
*
* @return a new request instance
* @throws IllegalArgumentException if required fields are missing
*/
public StartOutboundChatConversationRequest build() {
if (customerId == null || customerId.isBlank()) {
throw new IllegalArgumentException("customerId is required");
}
if (procedureId == null || procedureId.isBlank()) {
throw new IllegalArgumentException("procedureId is required");
}
if (supportPlatform == null || supportPlatform.isBlank()) {
throw new IllegalArgumentException("supportPlatform is required");
}
return new StartOutboundChatConversationRequest(this);
}
}
}
Loading
Loading