Creating a New Integration Package
Relevant source files
The following files were used as context for generating this wiki page: - [README.md](https://github.com/clearfeed/quix/blob/HEAD/README.md) - [link.sh](https://github.com/clearfeed/quix/blob/HEAD/link.sh) - [src/lib/constants.ts](https://github.com/clearfeed/quix/blob/HEAD/src/lib/constants.ts) - [src/slack/views/app_home.ts](https://github.com/clearfeed/quix/blob/HEAD/src/slack/views/app_home.ts) - [agent-packages/packages/assetpanda/README.md](https://github.com/clearfeed/quix/blob/HEAD/agent-packages/packages/assetpanda/README.md) - [agent-packages/packages/github/src/schema.ts](https://github.com/clearfeed/quix/blob/HEAD/agent-packages/packages/github/src/schema.ts) - [package.json](https://github.com/clearfeed/quix/blob/HEAD/package.json) - [src/slack/slack-events-handler.service.ts](https://github.com/clearfeed/quix/blob/HEAD/src/slack/slack-events-handler.service.ts)Quix's functionality is extended through a modular architecture that allows for the addition of new integrations. These integrations are self-contained packages that provide the AI agent with tools to interact with various business services like JIRA, GitHub, and HubSpot. Creating a new integration package involves developing a set of standardized files, defining the tools the agent can use, and registering the package within the main Quix application.
This guide outlines the structure of an integration package, the development workflow, and the process for integrating it into the Quix platform. The system is built on a Nest.js monorepo structure, with integration packages located in the agent-packages/ directory.
Sources: README.md:1-3, 22-37
Package Architecture
The Quix project uses a monorepo structure to manage its various components. All integration packages reside within the agent-packages/packages/ directory. Each subdirectory here represents a distinct integration.
Sources: README.md:22-37
This diagram illustrates the high-level project structure, highlighting where new integration packages fit in.
Sources: README.md:22-37
Development Workflow
Creating and integrating a new package follows a clear, multi-step process, from setting up the directory structure to linking the final package for local development.
This flowchart shows the end-to-end process for creating a new integration.
Sources: README.md:144-153, link.sh, src/lib/constants.ts:3-15
1. Create Package Directory
The first step is to create a new directory for your integration inside agent-packages/packages/. The directory name should be the name of the service (e.g., new-integration).
cd agent-packages/packages
mkdir new-integration
Sources: README.md:145-147
2. Standard Package Structure
Each integration package should follow a consistent file structure to ensure maintainability and compatibility with the core application.
| File | Description | Example Source |
|---|---|---|
package.json | Defines package metadata, dependencies, and scripts. The name should follow @clearfeed-ai/quix-<name>-agent. | agent-packages/packages/assetpanda/package.json:2 |
src/index.ts | The main entry point. Implements the service class and core logic for interacting with the external API. | agent-packages/packages/assetpanda/README.md:100-101 |
src/tools.ts | Defines the QuixTool instances that the LLM agent will use. Exports a create...ToolsExport function. | agent-packages/packages/assetpanda/README.md:102 |
src/types.ts | Contains TypeScript interfaces for the integration's configuration, API responses, and other data structures. | agent-packages/packages/assetpanda/README.md:103 |
src/schema.ts | Contains Zod schemas for validating the inputs to the tools. These schemas also provide descriptions for the LLM. | agent-packages/packages/assetpanda/README.md:104, agent-packages/packages/github/src/schema.ts |
Sources: agent-packages/packages/assetpanda/README.md:99-105, agent-packages/packages/assetpanda/package.json
3. Defining Tools and Schemas
The core of an integration is the set of "tools" it provides to the AI agent. Each tool is a function the agent can call.
Schemas with Zod
Input validation and LLM function-calling definitions are managed using Zod schemas. A schema is defined for each tool, specifying its arguments, descriptions, and default values. The descriptions are critical, as they inform the LLM about what the tool does and when to use it.
A helper function createConditionalDefaultSchema is often used to set default values for parameters like repo and owner if they are pre-configured, otherwise marking them as required.
// agent-packages/packages/github/src/schema.ts:4-8
const createConditionalDefaultSchema = (configValue: string | undefined, description: string) => {
return configValue
? z.string().describe(description).default(configValue)
: z.string().describe(`${description} (required)`);
};
// agent-packages/packages/github/src/schema.ts:86-98
export const createGithubIssueSchema = (config: GitHubConfig) =>
z.object({
repo: createConditionalDefaultSchema(
config.repo,
'The GitHub repository name where issue will be created'
),
owner: createConditionalDefaultSchema(config.owner, 'The owner of the repository'),
title: z.string().describe('The title of the issue'),
description: z
.string()
.nullish()
.transform((val) => val ?? undefined)
.describe('The description of the issue'),
assignee: z
.string()
.nullish()
.transform((val) => val ?? undefined)
.describe('The GitHub username of the assignee (optional)')
});
Sources: agent-packages/packages/github/src/schema.ts:4-8, 86-98
Creating Tools
The tools.ts file uses the schemas and the service logic from index.ts to create QuixTool instances. These are then exported via a create<IntegrationName>ToolsExport function, which is consumed by the main application.
Sources: agent-packages/packages/assetpanda/README.md:50-53, src/slack/views/app_home.ts:31-34
4. Registering the New Integration
To make the application aware of the new integration, it must be registered in several key places.
Constants File
Add your new integration to the SUPPORTED_INTEGRATIONS enum and the INTEGRATIONS array in src/lib/constants.ts. The INTEGRATIONS array holds metadata used throughout the application, such as for UI text and suggested prompts.
| Property | Description |
|---|---|
name | The display name of the integration (e.g., 'GitHub'). |
value | The enum value from SUPPORTED_INTEGRATIONS. |
helpText | A short description shown when the tool is not connected. |
connectedText | A confirmation message shown after successful connection. |
relation | The name of the relation on the SlackWorkspace model for this integration's config. |
oauth | A boolean indicating if the integration uses OAuth for authentication. |
suggestedPrompt | An example prompt to suggest to users. |
oneLineSummary | A very brief summary of the integration's purpose. |
Sources: src/lib/constants.ts:3-23, 38-48
// src/lib/constants.ts:3-15
export enum SUPPORTED_INTEGRATIONS {
JIRA = 'jira',
GITHUB = 'github',
HUBSPOT = 'hubspot',
// ...
JUMPCLOUD = 'jumpcloud',
NEW_INTEGRATION = 'new_integration' // Add new integration here
}
// src/lib/constants.ts:38-48
export const INTEGRATIONS: { ... }[] = [
{
name: 'JIRA',
value: SUPPORTED_INTEGRATIONS.JIRA,
// ...
},
// ... Add new integration object here
];
Sources: src/lib/constants.ts:3-15, 38-48
App Home UI
The integration needs to be added to the App Home view so users can connect to it. The getToolConnectionView function in src/slack/views/app_home.ts partitions the INTEGRATIONS list into connected and non-connected groups to display in a dropdown. The create...ToolsExport function is also called here to display the available functions for a selected tool.
Sources: src/slack/views/app_home.ts:188-202, 59-63
The following diagram shows how a user connecting an integration from the Slack App Home triggers the installation flow.
5. Build and Link the Package
For local development, the new package must be built and linked to the main application. The link.sh script automates this process. It iterates through each package in agent-packages/packages, links the shared common package, and then registers each integration package with yarn link. Finally, it links all the agent packages into the root project.
./link.sh
Sources: README.md:152-153, link.sh
The script performs the following key actions:
- Links
@clearfeed-ai/quix-common-agent. - Loops through each integration package directory.
- Inside each package, it runs
yarn link "@clearfeed-ai/quix-common-agent"if it's a dependency. - It runs
yarn linkto make the current package linkable. - In the project root, it links all agent packages (e.g.,
yarn link "@clearfeed-ai/quix-github-agent").
Sources: link.sh:7-34
Conclusion
Creating a new integration package for Quix is a structured process that enhances the AI agent's capabilities. By following the monorepo conventions, defining tools with clear schemas, and registering the integration within the main application, developers can seamlessly extend Quix to interact with a wide array of external services. The use of standardized package structures and a linking script simplifies the development and testing workflow, promoting a scalable and maintainable codebase.
Sources: README.md:22-37, 144-153