Beta
Please contact a Glean representative if you are interested in partnering with Glean and building actions on Glean’s platform.
Example actions
In this document, we will explore various examples that demonstrate how to enhance the capabilities of Glean Assistant by incorporating knowledge not already indexed in Glean's systems. Additionally, we'll show you how to enable Glean Assistant to perform specific "Actions," such as creating Jira issues or Salesforce cases. Before diving into this guide, please make sure you have gone through the Introduction and Getting Started pages to gain an understanding of the Glean actions framework.
Example of an execution action that allows Glean Assistant to update Google Documents
In this example, we will create a Google Doc Updater action from scratch. This action can help perform any operation on a pre-existing document. This example helps to demonstrate a full walkthrough of how actions are set up. This will also act as a guide for using OpenAPI specs with nested parameters.
Step 1: Finding the right OpenAPI Spec
The first step is to find the right OpenAPI Spec. For this, we will call the following HTTP request:
POST https://docs.googleapis.com/v1/documents/{documentId}:batchUpdate
- OpenAPI specs for Google APIs usually aren't made available by Google. You can rely on the documentation made publicly available by Google here and construct a spec yourself with some help from Glean Assistant. If you want the entire raw OpenAPI spec, you can use 3rd party sources such as this (which contain API specs for all the paths in Google Docs API).
- Glean Assistant uses the OpenAPI specification to understand the requirements of the server. We can thus form a well-defined valid request. When the user creates an action with a particular API spec, the action determines the URL and path to hit from these API spec fields. To make a valid request, we need to properly populate the request body, path parameter, and query parameter fields. The LLM is responsible for filling these fields correctly taking into account the properties like: type, enums, descriptions, and required. Some other fields like format, min, max, default, example, are also helpful to determine the field value. When the user makes a query that triggers this action, LLM fills the relevant fields and the response is displayed to the user giving him a chance to validate and edit the LLM filled fields before making the actual request.
-
Whatever source you choose, we must ensure that the final OpenAPI
spec you use conforms to the abovementioned rules. To do that, we
will:
-
Remove all the unnecessary paths and HTTP methods. There should
only be a
/v1/documents/{documentId}:batchUpdate
path with aPOST
HTTP request. - You can delete any unnecessary fields from the request body. In this example, we removed a lot of operations and decided to keep only the insertText and replaceAllText operations.
-
You can simplify the schema of the response body with a string
for write actions. In most cases, we do not consume the response
body fields. Just note that fields like resultUrl from the
responseBody may be used to plumb the correct Url to the end
user for execute write actions. Example of simplification:
responses: '200': description: OK content: application/json: schema: type: string
Or even something as simple as:
responses: '200': description: Successful Response
- For ease while editing, resolve all the references (if any). We do support refs but editing while keeping refs is a bit trickier. Here is a list of all the OpenAPI spec features we currently support. You can use any online/dev tools for this. Some helpful tools: [NPM] , [Golang] , [Java] .
-
For this particular example I resolved all the
$refs
first, then deleted some unnecessary keys (including the ones for sectionId) and updated the field description and titles in a few cases. You can even define enums, maxItems (for arrays only) and required fields. - Filling the descriptions is an important step to guide the Action on how we want it to populate certain fields. You can see that I removed some unnecessary descriptions (from the 3rd Party API spec) and added some description of my own (for eg. the description for documentId in path parameters). Without the proper description for documentId, the Action wouldn't be able to locate which google document to update hence failing the request.
- In the case of enum type values with not-so-descriptive values, you should describe the meaning of those values in the description field of the key.
-
Filling the Title for simple fields within the OpenAPI spec is
optional but strongly recommended to provide the end-users a human
readable way of understand the meaning of each field to be filled.
In the given example, I've filled one for the
matchCase
key. -
Incase of single-dimensional arrays, the simple fields are appended
with a 1-based array index after the human-readable title. However,
they're not supported for arrays with more than one dimensions,
hence we fallback. For cases where the title is the same for two
distinct keys within the OpenAPI spec, we fallback for all the keys.
For any key fallback, we generate a prettified version of the key
name. For example a key of type:
request[2].address.city
gets converted intoRequest <3> → Address → City
. -
Glean's internal typehints can be used in certain scenarios for
example emails or text-content. In the API spec below, we could've
added a
x-glean-typehint: Content
for the text field under the insertText operation. This would've saved us writing a detailed description for the text field, and just the first line: The text to be inserted. would've been enough. - For any arrays, you can define a maxItems field. The max possible number of elements will be bound by this and every sub-element within the item schema also contributes to the total number of valid keys counted by a factor of maxItems.
-
We have a hard limit of 15 keys max for any action. For example,
below we have 5 simple keys (2 from insertText and 3 from
replaceAllText). Since these properties come under the
requests
schema, they're multiplied by 2 i.e. our final keys are 10 from requestBody and 1 key from the parameter. These 11 keys are well under 15 keys, thus we support this OpenAPI specification in our action.
-
Remove all the unnecessary paths and HTTP methods. There should
only be a
- By the end, your OpenAPI spec may look something like this (note the description and title fields we added/edited/removed):
openapi: 3.0.0
servers:
- url: 'https://docs.googleapis.com/'
info:
description: Writes Google Docs documents.
title: Google Docs API
version: v1
paths:
'/v1/documents/{documentId}:batchUpdate':
post:
description: >-
Applies one or more updates to the document. Each request is validated
before being applied. If any request is not valid, then the entire
request will fail and nothing will be applied. The updates in your request
are guaranteed to be applied together atomically.
operationId: docs.documents.batchUpdate
parameters:
- description: >-
The ID of the document to update. Use glean search to find
the relevant document. The documentId usually exists in the
url of the doc. The syntax of URL (with documentId) is like:
https://docs.google.com/document/d/<documentId>/edit
Extract out the documentId from the URL.
in: path
name: documentId # 1 key
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
requests: # 10 keys
type: array
maxItems: 2
items: # 5 keys
type: object
properties:
insertText: # 2 keys
description: >-
Inserts text at the specified location. Always use this
operation except when text deletion or text replacement
is required.
type: object
properties:
location:
type: object
properties:
index:
description: >-
The zero-based index, in UTF-16 code units.
Strictly use a value of 1 and nothing else.
format: int32
type: integer
text:
description: >-
The text to be inserted. This is the most important field
for this text inserting operation. Insert a neatly
formatted text consisting of multiple paragraphs. Whenever
required, always start with a new line for paragraphs,
tables, lists for neatness. Use bullet icons (or
numbers for a numbered list) for any list. If user
requires a table, use ASCII characters for generating a
SQL style table. Use plaintext to form neat and formatted
text as much as possible.
type: string
replaceAllText: # 3 keys
description: >-
Replaces all instances of the specified text.
Always use this operation when text deletion
or text replacement is required.
type: object
properties:
containsText: # 2 keys
type: object
properties:
matchCase:
description: >-
Indicates whether the search should respect
case: - `True`: the search is case sensitive.
- `False`: the search is case insensitive.
type: boolean
title: Do you want to match case
text:
description: The text to search for in the document.
type: string
replaceText:
description: >-
The text that will replace the
matched text. Keep empty for deletion.
type: string
responses:
'200':
description: Successful response
- Feel free to remove any verbose fields (tags, info, x-(internal) fields, external docs, security) from this API Spec. Your API Spec is ready for use. We're mainly concerned with only a few sections under the servers (url) and paths fields (parameters, requestBody).
Step 2: Creating the action from scratch
- Go to Admin console > Platform > Actions , and click on the "New Action" button.
- Select start from scratch, since the Google Docs action isn't available in the templates.
- Basic Information: Fill this section with information like display name, description, and unique identifier. We will use the unique identifier throughout the oAuth, action-testing, and setup phase. Ensure that the action type is Action because this action will update a Google doc on our behalf.
- Trigger Condition: Please provide a detailed description of the action along with detailed instructions on when (in what cases) this action must be invoked/used by the Glean assistant. Also specify any information on when this action should not be invoked.
- Functionality : Fill in the modified OpenAPI spec we made in step 1 of this tutorial. We are not using a server hosted in our private network (on-prem server) for this and are directly hitting Google API servers. Thus, we don't need to tick the "Use existing on-premise server to proxy requests from this Action" section.
- After this, please authorize the action with OAuth2.0 verification. Choose oAuth Admin. For further steps, we first need to authorize the Glean action in the Google APIs dashboard.
Step 3: Authorizing the action
First, authorize this action with proper permissions and credentials. Here, let's follow the example of how to configure the Authorization for Google APIs.
- Ensure that you log in as an admin (with enough permissions) into the GCP where you will authorize the action. Visit https://console.cloud.google.com/apis/credentials .
- Click on Create credentials and select the OAuth Client ID.
- Select "Web Application" as the Application Type and give a name to your oAuth client.
- Assign "Authorized redirect URIs" (not the "Authorized JavaScript origins" section) to validate the actions's auth from Glean's backend. Add this URI:
https://{{your-glean-domain-name}}-be.glean.com/tools/oauth/verify_code/{{your-action-unique-identifier-name}}
For example:
https://{{your-glean-domain-name}}-be.glean.com/tools/oauth/verify_code/updateGoogleDoc
Ensure that you fill in the unique identifier name of the action and not the display name of the action. Please note that the unique identifier for your action is case sensitive. To get your glean domain name, follow the steps here.
- Click the save button and you will get access to the client ID and client secret. If not, you can create a new secret too. Note that you can also use another pre-existing client ID too. Just add the new URI to the existing URIs list.
- Go back to the glean's action creation page and in the Authentication window, fill in the client ID and client secret we got from the oAuth client.
- Fill in the following client URL, auth URL, and scopes:
Client URL: https://accounts.google.com/o/oauth2/auth?prompt=consent&access_type=offline
Authorization URL: https://accounts.google.com/o/oauth2/token
Scopes: https://www.googleapis.com/auth/documents
These details are usually present in the oAuth section of the API documentation for that action. Save the action. The final view should be something like this:
- Turn on Google Docs API for your GCP project from here:
https://console.cloud.google.com/apis/api/docs.googleapis.com/metrics?project={{your-gcp-project-name}}
Enable the Docs API. It should look something like this after turning it on:
- Now that we've done all this, return to the Glean's action creation page again. If you haven't saved the action yet, click save. Now, click on the "Authorize Action" button. It should redirect you to Google's Authorization page. You may have to sign in. Once done and successful, you will be redirected to the original action creation page.
- You should see the green tick establishing that you've authorized your action.
Step 4: Deploy and Use the action
Now that we've successfully created the action, it's time to test it out.
- To briefly test the action, you can click the link shown below "Test your Action at this URL". Note that this can only be tested by the action creator.
- Issue a query on this new URL, you should see the query executed and a box should appear to "Review and confirm" the action.
- Let's check the state of the document before issuing the query.
- Click on "Review and confirm". A window will pop up. Check the documentId and other fields of the document and make necessary changes if required.
- The field names shown here are taken from the title of each field in the API Spec. To ensure that more user friendly names are shown here, please add title to each field in the API Spec.
- Once this is done, click on the Save Changes button. Once the pinwheel appears and disappears, you should either see an error message or the same screen back.
- If there is an error, maybe it's an authentication issue. Try to resolve this on your end and if required, reach out to us.
- If it returns to the same screen, cross the box and visit that same document. You would likely see the document in the Reading section. Let's see the doc after the call is made.
- Great! This call was successful and has replaced the text while ignoring the case.
- Once you've tested this out, you can deploy this action to Chat or AI Apps. Head to the deploy tab, right next to the setup tab on the action creation page.
- As an admin, you can choose to enable this for all teammates or some teammates. These settings can only be modified by the admin. Once done with this, click on the save button and you should be able to run the action in normal chat flow if it's enabled for you.
Example of a retrieval action that allows Glean Assistant to fetch Google calendar events
Step 1: Creating the action from scratch
- Go to Admin console > Platform > Actions , and click on the "New Action" button.
- Select start from scratch, since the Google Calendar action isn't available in the templates.
- Basic Information: Fill this section with information like display name, description, and unique identifier. We will use the unique identifier throughout the OAuth, action testing, and setup phase. Ensure that the action type is Read because this action will read Google Calendar events on our behalf.
- Trigger Condition: Please provide a detailed description of the action along with detailed instructions on when (in what cases) this action must be invoked/used by the Glean assistant. Also specify any information on when this action should not be invoked.
-
Functionality
: Fill in the OpenAPI spec for the Google Calendar Events API.
Note: Please ensure the spec contains only one path/endpoint
openapi: 3.0.1
servers:
- url: 'https://www.googleapis.com/calendar/v3/'
info:
title: Google Calendar Events API
description: This API returns events on the primary calendar of the currently logged-in user.
version: 1.0.0
paths:
/calendars/primary/events:
get:
summary: List Events
description: Retrieves events from the primary calendar.
parameters:
- name: timeMin
in: query
description: |
Lower bound (exclusive) for an event's start time to filter by. Must be an RFC3339 timestamp with a mandatory time zone offset. Its very important to have timestamp in Z format
Example: 2011-06-03T10:00:00Z
required: false
schema:
type: string
format: date-time
- name: timeMax
in: query
description: |
Upper bound (exclusive) for an event's start time to filter by. Must be an RFC3339 timestamp with a mandatory time zone offset. Its very important to have timestamp in Z format
Example: 2011-06-03T10:00:00Z
required: false
schema:
type: string
format: date-time
- name: q
in: query
description: Free text search terms to find events that match these terms in various fields such as summary, description, location, etc.
required: false
schema:
type: string
responses:
'200':
description: A list of events.
content:
application/json:
schema:
type: object
properties:
kind:
type: string
description: Type of the collection ("calendar#events").
summary:
type: string
description: Title of the calendar. Read-only.
description:
type: string
description: Description of the calendar. Read-only.
updated:
type: string
format: date-time
description: Last modification time of the calendar.
timeZone:
type: string
description: The time zone of the calendar. Read-only.
accessRole:
type: string
description: The user's access role for this calendar.
defaultReminders:
type: array
items:
type: object
properties:
method:
type: string
description: The method used by this reminder. Possible values are "email" or "popup".
minutes:
type: integer
description: Number of minutes before the start of the event when the reminder should trigger.
items:
type: array
items:
type: object
properties:
id:
type: string
description: Identifier of the event.
status:
type: string
description: Status of the event (confirmed, tentative, cancelled).
summary:
type: string
description: Title of the event.
description:
type: string
description: Description of the event.
start:
type: object
properties:
dateTime:
type: string
format: date-time
description: The start time of the event.
end:
type: object
properties:
dateTime:
type: string
format: date-time
description: The end time of the event.
'400':
description: Invalid request.
'401':
description: Authorization required.
'403':
description: Forbidden request.
'404':
description: Calendar not found.
- We are not using a server hosted in our private network (on-prem server) for this and are directly hitting Google API servers. Thus, we don't need to tick the "Use existing on-premise server to proxy requests from this Action" section.
- After this, please authorize the action with OAuth2.0 verification. Choose OAuth User. For further steps, we first need to authorize the Glean action in the Google APIs dashboard.
Step 2: Authorizing the action
First, authorize this action with proper permissions and credentials. Here, let's follow the example of how to configure the Authorization for Google APIs.
- Ensure that you log in as an admin (with enough permissions) into the GCP where you will authorize the action. Visit https://console.cloud.google.com/apis/credentials .
- Click on Create credentials and select the OAuth Client ID.
- Select "Web Application" as the Application Type and give a name to your oAuth client.
- Assign "Authorized redirect URIs" (not the "Authorized JavaScript origins" section) to validate the actions's auth from Glean's backend. Add this URI:
https://{{your-glean-domain-name}}-be.glean.com/tools/oauth/verify_code/{{your-action-unique-identifier-name}}
For example:
https://{{your-glean-domain-name}}-be.glean.com/tools/oauth/verify_code/retrieveCalendarEvents
Ensure that you fill in the unique identifier name of the action and not the display name of the action. Please note that the unique identifier for your action is case sensitive. To get your glean domain name, follow the steps here.
- Click the save button and you will get access to the client ID and client secret. If not, you can create a new secret too. Note that you can also use another pre-existing client ID too. Just add the new URI to the existing URIs list.
- Go back to the glean's action creation page and in the Authentication window, fill in the client ID and client secret we got from the oAuth client.
- Fill in the following client URL, auth URL, and scopes:
Client URL: https://accounts.google.com/o/oauth2/auth?prompt=consent&access_type=offline
Authorization URL: https://accounts.google.com/o/oauth2/token
Scopes: https://www.googleapis.com/auth/calendar.readonly
These details are usually present in the OAuth section of the API documentation for that action. Save the action. The final view should be something like this:
- Turn on Google Calendar API for your GCP project from here:
https://console.cloud.google.com/apis/api/calendar-json.googleapis.com/metrics?project={{your-gcp-project-name}}
Enable the Calendar API. It should look something like this after turning it on:
- Now that we've done all this, return to the Glean's action creation page again. If you haven't saved the action yet, click save.
Step 3: Deploy and Use the action
Now that we've successfully created the action, it's time to test it out.
- To briefly test the action, you can click the link shown below "Test your Action at this URL". Note that this can only be tested by the action creator.
- Issue a query on this new URL, you should see a banner asking you to allow the action. Click on the Connect button and authenticate with your Google account.
- After successful authentication, you should see the query executed and the calendar events should be displayed.
- Once you've tested this out, you can deploy this action to Chat or AI Apps. Head to the deploy tab, right next to the setup tab on the action creation page.
- As an admin, you can choose to enable this for all teammates or some teammates. These settings can only be modified by the admin. Once done with this, click on the save button and you should be able to run the action in normal chat flow if it's enabled for you.
Example of an execution action that allows Glean Assistant to create Jira issues
First, you would need to create an action manifest that describes basic properties of an action. See Defining a action manifest to learn more about creating a manifest for different types of actions. For an execution action with OAuth based authentication, the manifest would look like this -:
{
"type": "ACTION",
"name": "CreateJiraIssue",
"displayName": "Create Jira Issue Action",
"description": "This action allows you to create a new issue in Jira. You can specify the project, issue type, and other details.",
"enablePreview": true,
"actionType": "EXECUTION",
"logoUrl": "path/to/your/logo.png",
"auth": {
"type": "OAUTH_ADMIN",
"client_url": "https://auth.atlassian.com/authorize?audience={ATLASSIAN-DOMAIN}.atlassian.net&prompt=consent",
"scopes": [
"write:jira-work",
"offline_access",
"read:me"
],
"authorization_url": "https://auth.atlassian.com/oauth/token"
}
}
Here we are using auth.type
as OAUTH_ADMIN
since jira allows using admin tokens to create issues using their cloud API on behalf of other users.
For use cases, where each user needs to OAuth, you would need to use OAUTH_USER
as auth.type
.
Now we need to implement a server that Glean actions backend will call to create Jira issues. Note that the action server should follow the guidelines listed in Defining an action API spec. The three guidelines applicable here are -:
- The action server should validate that the request is coming from Glean.
- Fields in the action server api specification should not be nested.
-
The action server should use
Glean-User-Email
to fetch events on behalf of the user triggering the action from Glean Assistant. The server should not allow users to get events by impersonating other users.
In Glean Assistant UI, users have the ability to authenticate themselves using OAuth for various actions. Glean also takes care of managing OAuth tokens for all users connected to these actions. Depending on the action configuration, the backend of Glean sends the relevant OAuth token as a Bearer
token in the Authorization
header. For actions set up as OAUTH_ADMIN
, the admin OAuth token is used. Conversely, for OAUTH_USER
configured actions, the token of the user initiating the request from the Glean Assistant is used. The action server can then use this token to interact seamlessly with Jira APIs.
Note:
A distinct feature of this Jira issue creation action is its handling of the reporter ID field. Unlike conventional setups, we aim to have the reporter ID always match the user who initiates the issue creation via the Glean Assistant interface. To achieve this, we utilize a specific header, Glean-User-Email
, to fetch the appropriate reporter ID for inclusion in the issue creation request. This approach serves as an example of how we selectively prevent certain fields from being populated by large language models.
Here is how the server would look like in python -:
from flask import Flask, request, jsonify
import requests
import json
app = Flask(__name__)
cloud_id = "your_jira_cloud_id_here"
create_issue_url_format = f"https://api.atlassian.com/ex/jira/{cloud_id}/rest/api/3/issue"
users_search_url = f"https://your-domain.atlassian.net/rest/api/3/users/search"
def get_reporter_id(email, auth_header):
start_at = 0
max_results = 50
while True:
params = {'startAt': start_at, 'maxResults': max_results}
headers = {'Accept': 'application/json', 'Authorization': auth_header}
response = requests.get(users_search_url, params=params, headers=headers)
users = json.loads(response.text)
for user in users:
if user['emailAddress'] == email:
return user['accountId']
if len(users) < max_results:
break
start_at += max_results
return None
def transform_to_jira_request(input_payload, reporter_id):
jira_request = {
"fields": {
"project": {"id": input_payload['pid']},
"issuetype": {"id": str(input_payload['issuetype'])},
"priority": {"id": str(input_payload['priority'])},
"summary": input_payload['summary'],
"components": [{"id": input_payload['components']}],
"description": {
"type": "doc",
"version": 1,
"content": [{"type": "text", "text": input_payload['description']}]
},
"assignee": {"id": input_payload['assignee']},
"reporter": {"id": reporter_id}
}
}
return jira_request
@app.route('/create_issue', methods=['POST'])
def create_issue():
authorization_header = request.headers.get('Authorization')
glean_user_email = request.headers.get('Glean-User-Email')
if authorization_header is None or glean_user_email is None:
return jsonify({"error": "Authorization header or Glean-User-Email not found"}), 401
reporter_id = get_reporter_id(glean_user_email, authorization_header)
if reporter_id is None:
return jsonify({"error": "Reporter ID not found"}), 400
input_payload = request.json
jira_request = transform_to_jira_request(input_payload, reporter_id)
headers = {
"Content-Type": "application/json",
"Authorization": authorization_header
}
response = requests.post(create_issue_url_format, headers=headers, json=jira_request)
if response.status_code == 200:
return jsonify({"resultURL": json.loads(response.text).get("key")}), 200
else:
return jsonify({"error": "Failed to create issue", "details": response.text}), response.status_code
if __name__ == '__main__':
app.run(port=8080)
Finally, we need to define an API spec for the action server. This API spec will be used by Glean Assistant to interact with the action server, so we should make it as descriptive as possible. Here's how the API specification would appear for our create Jira issue action:
---
openapi: 3.0.0
info:
title: Jira Execution Action
version: 1.0.0
servers:
- url: https://{domain}-be.glean.com/tools/jira
variables:
domain:
default: domain
description: Email domain (without extension) that determines the deployment backend.
paths:
/create_issue:
post:
summary: Creates an issue or a sub-task from a JSON representation
description: |
This API allows you to create an issue in Jira.
parameters:
- name: Glean-User-Email
in: header
required: true
schema:
type: string
description: Email of the authenticated glean user.
requestBody:
content:
application/json:
schema:
type: object
properties:
pid:
x-glean-typehint: 'JiraProjectID'
type: string
description: Project ID where the ticket is created.
issuetype:
type: integer
description: The ID corresponding to the type of issue being created.
priority:
type: integer
minimum: 1
maximum: 5
description: Numeric priority. 1 (highest) to 5 (lowest).
summary:
x-glean-typehint: 'Content'
type: string
description: Title of the issue
components:
x-glean-typehint: 'JiraComponent'
type: string
description: Component name where the ticket should be filed.
description:
x-glean-typehint: 'Content'
type: string
description: Body of the issue.
assignee:
x-glean-typehint: 'JiraId'
type: string
description: User to which the issue is assigned.
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/CreateIssuePostResponse'
'400':
description: Bad Request
'401':
description: Not Authorized
'409':
description: Conflict
components:
schemas:
CreateIssuePostResponse:
type: object
properties:
resultURL:
type: string
description: URL of the created issue.
Example of a redirect action (using Redirect URL Builder) that allows Glean Assistant to create Zendesk tickets via redirecting to the Zendesk app
Begin by clicking “New Action” on the Actions settings page. The Redirect URL builder should appear as an option
Like other tools, you will need to enter the display name and description, the unique identifier and the trigger conditions. Tool type has been auto-populated for you. You can enter the URL builder from the Functionality section.
The best way to start is to copy a URL into the target URL field. Let’s say we want to build a Zendesk ticket creation action. Zendesk uses the query parameters passed in the URL (the new ticket creation url in this case) to auto-populate fields in the new ticket creation experience. From their documentation, we know that the URL must look like this:
Once we do that, the Redirect URL builder will look like this. Notice that the parameter names have been auto filled, along with a single allowed value from the given URL. At this point, these parameters are considered constants because they take on only one possible value.
Of course, creating the exact same ticket every time is rarely useful. We want Glean Assistant to be able to understand and fill in the new ticket’s description and subject every time. To do this, simply delete the allowed value and add the relevant instructions for Glean Assistant on how to fill it in under Description for LLM. In addition, if you set a parameter to be "Required", Glean Assistant will ensure that it is filled when generating the final URL.
What if we want to add more parameters? We can do it either by clicking “+Add Query Parameter” link at the bottom of the table:
Or by appending it directly to the URL:
If we want to limit the value of a parameter to a set of values, simply place these values in the Allowed Values section (hit Enter for each value). It’s usually good practice to describe how Glean Assistant should select among these values in the Description section.
Beyond these, we also support path parameters. To add a path parameter, simply enclose the parameter name at the desired location within the path. You can then configure the parameter like before. Note that all path parameters must be Required parameters.
Example of a redirect tool (using API Spec) that allows Glean Assistant to create Jira issues via redirecting to Jira app
First, you would need to create an action manifest that describes basic properties of a action. See Defining a action manifest to learn more about creating a manifest for different types of actions. For a redirect action action, the manifest would look like this -:
{
"type": "ACTION",
"name": "JiraCreateTicket",
"description": "This action allows you to create a new issue in Jira. You can specify the project, issue type, and other details.",
"enablePreview": true,
"actionType": "REDIRECT"
}
In the case of redirect actions, there's no need to implement or host a server. Our role is solely to generate a URL that navigates the user directly to the resource creation interface within the target application — in our instance, the issue creation workflow in the Jira app. Glean Assistant takes care of pre-filling all required fields according to the API specification. Therefore, all we need to do is to create a comprehensive API spec to guide this process. Here's a sample spec for reference:
openapi: "3.0.0"
info:
title: "Jira Create Ticket"
version: "1.0.0"
servers:
- url: "https://{YOUR-ATLASSIAN-DOMAIN}.atlassian.net/secure/CreateIssueDetails!init.jspa?"
paths:
/:
post:
summary: "Creates an issue or a sub-task from a JSON representation"
description: |
This API allows you to create a ticket or an issue in Jira.
parameters:
- name: "pid"
in: "query"
required: true
schema:
type: "string"
x-glean-typehint: "JiraProjectID"
default: "10000"
description: "Project ID where the ticket is created. 10000 refers to Engineering project."
- name: "issuetype"
in: "query"
required: true
schema:
type: "integer"
enum:
- 10002
- 10004
description: "Issue type. 10002 refers to Task, 10004 refers to Bug."
- name: "priority"
in: "query"
schema:
type: "integer"
minimum: 1
maximum: 5
description: "Numeric priority. 1 (highest) to 5 (lowest)."
- name: "summary"
in: "query"
required: true
schema:
type: "string"
x-glean-typehint: "Content"
description: "Title of the issue."
- name: "components"
in: "query"
schema:
type: "string"
x-glean-typehint: "JiraComponent"
description: "Component name where the ticket should be filed."
- name: "description"
in: "query"
schema:
type: "string"
x-glean-typehint: "Content"
description: "Body of the issue."
- name: "assignee"
in: "query"
schema:
type: "string"
x-glean-typehint: "JiraId"
description: "User to which the issue is assigned."
responses:
'200':
description: "OK"
content:
application/json:
schema:
type: "string"
One thing to note here is that the API specification includes illustrative examples in the parameter descriptions, such as specifying that a pid
of "10000" corresponds to the Engineering project or that "10002" and "10004" refer to Task and Bug issue types, respectively. Examples like these enable Glean Assistant to accurately pre-fill the fields.
This is what it would look like on the Glean Assistant UI -: