<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lalit Indoria</title>
    <description>The latest articles on DEV Community by Lalit Indoria (@lalitindoria).</description>
    <link>https://dev.to/lalitindoria</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F586348%2F18d065fa-c21c-40f6-b1d0-5b08879d05a4.jpg</url>
      <title>DEV Community: Lalit Indoria</title>
      <link>https://dev.to/lalitindoria</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lalitindoria"/>
    <language>en</language>
    <item>
      <title>Building Quix: A Slack Agent to talk to your apps using natural language</title>
      <dc:creator>Lalit Indoria</dc:creator>
      <pubDate>Thu, 20 Feb 2025 19:21:18 +0000</pubDate>
      <link>https://dev.to/lalitindoria/building-quix-a-slack-agent-to-talk-to-your-apps-using-natural-language-2md9</link>
      <guid>https://dev.to/lalitindoria/building-quix-a-slack-agent-to-talk-to-your-apps-using-natural-language-2md9</guid>
      <description>&lt;p&gt;In today's fast-paced work environment, juggling multiple tools can be a major productivity challenge. Constantly switching between platforms for simple tasks is both time-consuming and frustrating. As someone who values efficiency in chat-based interactions, I envisioned a solution to streamline these tasks directly from Slack, a platform where my team and I communicate frequently. This inspired me to build &lt;a href="https://github.com/clearfeed/quix" rel="noopener noreferrer"&gt;Quix&lt;/a&gt; — an AI-powered Slack agent designed to handle various business tool queries seamlessly.&lt;/p&gt;

&lt;p&gt;I founded &lt;a href="https://clearfeed.ai" rel="noopener noreferrer"&gt;ClearFeed&lt;/a&gt;, a platform that helps teams provide support by integrating Slack with other tools. While ClearFeed offers extensive functionalities, I wanted to create something lightweight and focused, allowing teams to resolve conversations within Slack much faster. Here are some scenarios where interacting with tools within Slack proves to be incredibly useful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the status of the Asana integration?** (Query JIRA)&lt;br&gt;
Is the PR to support the chat widget closed?** (Query GitHub)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Beyond querying tools, an agent like Quix can handle even more complex workflows. Imagine effortlessly turning a long Slack thread into a Jira ticket:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0te7pkivouyp59wamfr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0te7pkivouyp59wamfr.png" alt="Image description" width="360" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqq71xha1148tl0nym82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqq71xha1148tl0nym82.png" alt="Image description" width="360" height="411"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Repository Structure and Tools Used
&lt;/h3&gt;

&lt;p&gt;The repository follows a &lt;strong&gt;TypeScript monorepo&lt;/strong&gt; structure, with each integration packaged as a separate module. This design ensures that the Express server handling Slack interactions remains independent from integration components, allowing for easy addition and deployment of new integrations. Integration packages reside in the &lt;code&gt;agent-packages/packages/&lt;/code&gt; directory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Tools and Libraries
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LangChain&lt;/strong&gt;: For managing language model interactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zod&lt;/strong&gt;: For schema validation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Express&lt;/strong&gt;: For handling API requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack Web API&lt;/strong&gt;: For interacting with Slack.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Why LangChain?
&lt;/h3&gt;

&lt;p&gt;LangChain provides uniform APIs, allowing me to query different language models without making significant code changes. This flexibility makes it easy to experiment with or swap models while maintaining a consistent integration structure. Additionally, LangChain, along with Zod, simplifies tool schema definitions, making it effortless to define new tools regardless of the model in use. This ensures that Quix remains highly adaptable and scalable as AI models evolve.&lt;/p&gt;




&lt;h3&gt;
  
  
  Writing Integrations
&lt;/h3&gt;

&lt;p&gt;Quix integrations are &lt;strong&gt;self-contained&lt;/strong&gt; and follow a &lt;strong&gt;consistent pattern&lt;/strong&gt;. Each integration package consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: An array of &lt;code&gt;DynamicStructuredTool&lt;/code&gt; instances from LangChain, encapsulating available functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt;: Customizable prompts for tool selection and response generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Classes&lt;/strong&gt;: API interaction handlers for respective platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, the GitHub integration includes tools for searching issues, managing user assignments for issues and pull requests, and fetching member details. Each function includes a description that helps the LLM determine the appropriate tool to invoke, with function arguments defined using Zod for clarity and validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DynamicStructuredTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search_github_issues&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Search GitHub issues or PRs based on status, keywords, and reporter. PRs and Issues are interchangeable terms in GitHub.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The name of the repository to search in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;issue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pull-request&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The type of issue or PR to search for&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The keyword to search for in issue or PR titles and descriptions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;reporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The GitHub username of the issue or PR author&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;func&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SearchIssuesParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;searchIssues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each integration exports the following prompts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;toolSelectionPrompt&lt;/code&gt; – Helps the LLM decide if this tool should be selected.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;responseGenerationPrompt&lt;/code&gt; – Instructs the LLM on how to generate a response based on the tool's specific requirements. For example, you can specify a hostname format when linking to Jira tickets.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Data Flow
&lt;/h3&gt;

&lt;p&gt;Here's a data flow diagram illustrating the processing in &lt;code&gt;llm.service.ts&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8gsuttg5d51h24ipcx6e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8gsuttg5d51h24ipcx6e.jpg" alt="Image description" width="692" height="1444"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Installing Quix on Slack
&lt;/h3&gt;

&lt;p&gt;Quix includes an Express server and a Slack app manifest, making it easy to set up a Slack app as an AI-powered assistant within Slack. To install it in your workspace:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Host the Express server&lt;/strong&gt; – You can use the included Dockerfile for deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a new Slack app&lt;/strong&gt; – Use the provided manifest file, ensuring that the &lt;code&gt;request_url&lt;/code&gt; matches your Express server’s endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install the app in your Slack workspace&lt;/strong&gt; – Populate the necessary environment variables, including the Slack Bot Token.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’re a Slack admin, consider &lt;strong&gt;pinning the app&lt;/strong&gt; in your workspace to ensure easy access for all team members.&lt;/p&gt;


&lt;h3&gt;
  
  
  Contributing to Quix
&lt;/h3&gt;

&lt;p&gt;Quix is an &lt;strong&gt;open-source project&lt;/strong&gt;, and community contributions are always welcome. If you're interested, you can install it in your Slack workspace, explore its functionalities, and share your feedback. Reporting issues, suggesting enhancements, or submitting pull requests on GitHub helps refine and expand Quix, making it even more effective for users.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/clearfeed" rel="noopener noreferrer"&gt;
        clearfeed
      &lt;/a&gt; / &lt;a href="https://github.com/clearfeed/quix" rel="noopener noreferrer"&gt;
        quix
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Query your business tools from Slack
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🚀 Quix: AI-Powered Slack Agent&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Quix is an AI-powered Slack agent that can interact with your business tools such as JIRA, GitHub, HubSpot and more. It allows users to interact with these services directly from Slack channels or through 1:1 chats.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🔗 Supported Integrations&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/c578892267b454d5ed986b5d92d0b807160cae7764801e1293548842178a363a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4a6972612d3030353243433f7374796c653d666f722d7468652d6261646765266c6f676f3d6a697261266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/c578892267b454d5ed986b5d92d0b807160cae7764801e1293548842178a363a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4a6972612d3030353243433f7374796c653d666f722d7468652d6261646765266c6f676f3d6a697261266c6f676f436f6c6f723d7768697465" alt="Jira"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/f1fbce44786ee4edcf97a717cce6c15cfc38a1f098efb08f11c1c80dd595a909/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4769744875622d3138313731373f7374796c653d666f722d7468652d6261646765266c6f676f3d676974687562266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/f1fbce44786ee4edcf97a717cce6c15cfc38a1f098efb08f11c1c80dd595a909/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4769744875622d3138313731373f7374796c653d666f722d7468652d6261646765266c6f676f3d676974687562266c6f676f436f6c6f723d7768697465" alt="GitHub"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/88dc24a3ca4cd6ab7291d8906d4843a323599f5572aaf34e2754ecb5d145f64f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f48756253706f742d4646374135393f7374796c653d666f722d7468652d6261646765266c6f676f3d68756273706f74266c6f676f436f6c6f723d7768697465"&gt;&lt;img src="https://camo.githubusercontent.com/88dc24a3ca4cd6ab7291d8906d4843a323599f5572aaf34e2754ecb5d145f64f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f48756253706f742d4646374135393f7374796c653d666f722d7468652d6261646765266c6f676f3d68756273706f74266c6f676f436f6c6f723d7768697465" alt="HubSpot"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/31df578f05ccac4fb80b5daf55c1f8f1c315107449965d79533aaf03d3ba345d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5a656e6465736b2d3033344636323f7374796c653d666c6174266c6f676f3d7a656e6465736b"&gt;&lt;img src="https://camo.githubusercontent.com/31df578f05ccac4fb80b5daf55c1f8f1c315107449965d79533aaf03d3ba345d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5a656e6465736b2d3033344636323f7374796c653d666c6174266c6f676f3d7a656e6465736b" alt="Zendesk"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Slack Integration&lt;/strong&gt;: Quix can respond to queries when tagged in Slack channels. 🗨️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Service Querying&lt;/strong&gt;: Supports querying multiple tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread Context&lt;/strong&gt;: Quix can understand the context of a Slack thread when answering queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Query Endpoint&lt;/strong&gt;: Exposes an endpoint to accept user queries. 🔍&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Setting Up the Slack App&lt;/h2&gt;

&lt;/div&gt;


&lt;ol&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Create a Slack App&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;a href="https://api.slack.com/apps" rel="nofollow noopener noreferrer"&gt;Slack API&lt;/a&gt; and create a new app.&lt;/li&gt;
&lt;li&gt;Choose "From an app manifest" and paste the contents of &lt;code&gt;slack_app_manifest.yml&lt;/code&gt; from this repository.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Update the Events Endpoint&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the manifest, replace &lt;code&gt;&amp;lt;EXPRESS_ENDPOINT&amp;gt;&lt;/code&gt; with your server's public URL where Slack can send event notifications.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;…&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/clearfeed/quix" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>ai</category>
      <category>agentaichallenge</category>
      <category>opensource</category>
      <category>langchain</category>
    </item>
  </channel>
</rss>
