Skip to main content

Dust Integration

Connect the Catalog AI Assistant to Dust so workspace users can ask data questions from Dust chat. You store a Catalog API token as a Dust app secret, build a Dust app that submits and polls the AI Assistant API, and attach that app to a Dust agent with a structured instruction prompt.

Prerequisites

  • You need admin access in Dust.
  • You need a Catalog API token with Read & Write scope. Catalog administrators create tokens in Settings > API. See Getting Your Catalog API Keys for generation and rotation steps.
  • Review Introduction to Dust apps if you are new to Dust app blocks.

Installation Overview

The Dust agent is created at the workspace level. Once set up, it is accessible to all users in your workspace.

  1. Set the Catalog API token as a Dust app secret named CATALOG_API_TOKEN.
  2. Create and configure the coalesceAiAssistant Dust app with the blocks in Build the Dust App Blocks.
  3. Create a Dust agent that runs the app as a tool and uses the Agent instruction prompt below.

Set the Catalog API Token as a Dust App Secret

Secrets let Dust apps reference sensitive values without exposing them in block definitions.

Create the CATALOG_API_TOKEN secret in Dust Developers settings
  1. Open the Admin tab in the top left menu.
  2. Go to Developers > Secrets in the left menu.
  3. Click Create Secret.
  4. Set the secret name to CATALOG_API_TOKEN, paste the token value, and click Create.

Create the Dust App Shell

Create an empty app before you add blocks:

  1. Go to the Spaces tab in the top left menu.
  2. Go to Open Spaces > Apps.
  3. Click Create a new app.
  4. Set the app name to coalesceAiAssistant and the description to Calling the Catalog AI Assistant to answer your question and show helpful assets.

The app calls the Catalog public API in two phases: submit a question with addAiAssistantJob, then poll getAiAssistantJobResult until the job completes. See AI Assistant API for the underlying GraphQL operations.

Build the Dust App Blocks

Add the following blocks to coalesceAiAssistant in this order. Block names are case-sensitive and must match the names referenced in the code.

BlockTypePurpose
INPUTinputReceives question, email, and conversationId from the agent
CONFIGcodeSets MAX_POLLS and DELAY_SECONDS reused by later blocks
GET_JOB_IDcurlSubmits the question to Catalog and returns a jobId
CHECK_JOB_IDcodeParses the GET_JOB_ID response and surfaces errors
POLLINGwhileLoops until the job reaches a terminal status or hits the poll limit
POLL_APIcurlNested inside POLLING; polls for the AI Assistant result
SUMMARYcodeFormats the final answer and assets for the agent

Use the API base URL that matches your Catalog region:

  • EU: https://api.castordoc.com/public/graphql
  • US: https://api.us.castordoc.com/public/graphql

Append the operation query parameter to each curl block URL, for example ?op=addAiAssistantJob or ?op=getAiAssistantJobResult.

INPUT Block

  1. On the Specification tab, click Add Block and add an input block.
  2. Set the block name to INPUT.
  3. Open Datasets, create a dataset named INPUT, and define these string fields: conversationId, email, and question.
  4. Return to Specification, select the INPUT block, and set Dataset to INPUT.
Dust app Specification tab with Add Block and input block option Dust INPUT dataset schema with conversationId, email, and question string fields Dust INPUT block with dataset set to INPUT

Configure Polling Constants

  1. Add a code block and name it CONFIG (the block name must match exactly).
  2. Paste this code:
_fun = (env) => {
const MAX_POLLS = 15;
const DELAY_SECONDS = 5;
return { MAX_POLLS, DELAY_SECONDS }
}

Your block should look like this:

Dust CONFIG code block with MAX_POLLS and DELAY_SECONDS constants

GET_JOB_ID Block

  1. Add a curl block and name it GET_JOB_ID.
  2. Set the request to POST with your region URL and ?op=addAiAssistantJob.
  3. Paste the Headers and Body code below into the block.
  4. Enable Results are computed at each run on the block settings.

Headers:

_fun = (env) => {
return {
"Content-Type": "application/json",
"Authorization": `Token ${env.secrets.CATALOG_API_TOKEN}`
};
}

Body:

const _fun = (env) => {
const { conversationId, email, question } = env.state.INPUT;

const toGraphQLString = (value) =>
JSON.stringify(String(value ?? '')).slice(1, -1);

const body = {
query: `
query {
addAiAssistantJob (
data: {
question: "${toGraphQLString(question)}"
email: "${toGraphQLString(email)}"
externalConversationId: "${toGraphQLString(conversationId)}"
origin: DUST
}
) {
data {
jobId
}
}
}
`
};

return JSON.stringify(body);
};
Dust block setting Results are computed at each run enabled Dust GET_JOB_ID curl block with POST request to Catalog GraphQL addAiAssistantJob

CHECK_JOB_ID Block

  1. Add a code block and name it CHECK_JOB_ID.
  2. Paste this code:
const _fun = (env) => {
const { errors, data } = env.state.GET_JOB_ID.body;

if (errors?.length) return { error: errors[0].message, jobId: '' };

return { error: '', jobId: data?.addAiAssistantJob?.data?.jobId || '' };
};

Your block should look like this:

Dust CHECK_JOB_ID code block parsing jobId from GET_JOB_ID response

POLLING and POLL_API Blocks

Add the polling loop and its nested curl block together.

  1. Add a while block and name it POLLING.
  2. Set the maximum iteration count to 20 in the block settings.
  3. Paste the condition code below into the block.
  4. Inside the POLLING block, add a curl block named POLL_API.
  5. Set the POLL_API request to POST with your region URL and ?op=getAiAssistantJobResult.
  6. Reuse the same Headers code as GET_JOB_ID, paste the Body code below, and enable Results are computed at each run on POLL_API.
POLL_API Nesting

Create POLL_API inside the POLLING block, not at the top level of the app.

POLLING condition:

const _fun = (env) => {
const { MAX_POLLS } = env.state.CONFIG;
const { jobId } = env.state.CHECK_JOB_ID;
const TERMINAL_STATUSES = ['completed', 'failed'];

const iteration = env.map?.iteration ?? 0;
const pollResponses = env.state.POLL_API;

if (!jobId || iteration > MAX_POLLS) return false;
if (!pollResponses?.length) return true;

const lastStatus = pollResponses.at(-1)?.body?.data?.getAiAssistantJobResult?.data?.status;

return lastStatus
? !TERMINAL_STATUSES.includes(lastStatus)
: true;
};

POLL_API Body:

const _fun = (env) => {
const { DELAY_SECONDS } = env.state.CONFIG;
const { jobId } = env.state.CHECK_JOB_ID;

const body = {
query: `
query {
getAiAssistantJobResult (
data: {
id: "${jobId}"
delaySeconds: ${DELAY_SECONDS}
}
) {
data {
status
answer
assets {
id
internalLink
name
url
}
}
}
}
`
};

return JSON.stringify(body);
};
Dust POLLING while block with max_iterations 20 and polling condition code Dust POLL_API curl block nested in POLLING with getAiAssistantJobResult request

SUMMARY Block

  1. Add a code block and name it SUMMARY.
  2. Paste this code:
const _fun = (env) => {
const { error } = env.state.CHECK_JOB_ID;
if (error) return { answer: error, assets: [] };

// Guard: POLL_API may be undefined if polling never ran (e.g. empty jobId)
if (!env.state.POLL_API?.length) {
return { answer: 'Unable to retrieve a job ID from the Catalog API. Please try again later.', assets: [] };
}

const result = env.state.POLL_API.at(-1)?.body?.data?.getAiAssistantJobResult?.data || {};
const { status, answer } = result;

if (status === 'failed') {
return { answer: answer || 'The AI Assistant job failed. Please try again later.', assets: [] };
}

if (status !== 'completed') {
return { answer: 'The AI Assistant job did not complete in time. Please try again later.', assets: [] };
}

const assets = (result.assets || []).map(({ name, url, internalLink }) => ({
name,
url: url || internalLink,
}));

return { answer: answer || '', assets };
};

Your block should look like this:

Dust SUMMARY code block formatting answer and assets for the agent

Create the Dust Agent

The CoalesceAiAssistant agent runs the coalesceAiAssistant app as a tool and formats responses for Dust users.

  1. Click Create > New Agent.
  2. Set Advanced settings: Model selection Claude Sonnet, recommended. Creativity level Deterministic, recommended.
  3. Copy and paste the Agent instruction prompt into the instructions field, then click Next.
  4. Remove all existing tools, then click Add tools > Run Dust app.
  5. Select the coalesceAiAssistant app and click Save, then Next.
  6. Name the agent CoalesceAiAssistant, update the icon, test in the bottom-right corner, and set access to Published.

Agent Instruction Prompt

Paste this prompt into the agent instructions field:

You are an assistant that answers user questions by querying a knowledge base tool. Your role is to process questions and return clean, structured responses.

## Process Flow

When a user asks a question:

1. Extract inputs
- User's question from their message
- User's email from system context
- Conversation ID from system context: conversation_id

2. Call the tool with these parameters
- question: string
- email: string
- conversationId: string

3. Process the JSON response

The tool returns this structure:

{
"answer": "string - the answer to the user's question",
"assets": [
{
"name": "string - display name for the asset",
"url": "string - link to the asset"
}
]
}

## Response Format

Structure your response exactly as follows:

- Display the answer from the answer field
- List assets when the assets array is not empty:
- Format each asset as a Markdown link: [asset.name](asset.url)
- Put each asset link on a separate line

## Error Handling

- If the answer is "NotFound: User was not found", respond: "You need a Coalesce Catalog account to use this assistant. Please contact your organization's admin to request access. They can set up your account with the necessary permissions."
- If the tool fails or returns an error: "I'm unable to process your request right now. Please try again later."

## Important Rules

- No additional commentary. Only include the answer and asset links.
- No explanations beyond what the tool provides.
- Always validate that assets have both name and url fields before formatting.
- Handle empty responses gracefully. Display the answer even when there are no assets.
- Maintain consistent formatting for all asset links.

Debug

  • Tool inspection in the chat: Click Tool inspection in your chat box to view both the input and output of the tool.
  • Tool logs: Each response from CoalesceAiAssistant triggers a tool call to coalesceAiAssistant. View a detailed log of every call, including step-by-step output, by going to the app Logs > API.

Update

  • The Dust agent uses the AI Assistant public API, so updates to the AI Assistant on the Catalog side are reflected in Dust automatically. Updates on the Catalog side are designed to be backward compatible. Catalog notifies you if an update requires action on your part.
  • Because the Dust app and agent live in your Dust workspace, you are responsible for updating them when needed. Catalog notifies you if an update is required.

What's Next?