Request Lifecycle
Relevant source files
The following files were used as context for generating this wiki page: - [src/slack/slack-events-handler.service.ts](https://github.com/clearfeed/quix/blob/HEAD/src/slack/slack-events-handler.service.ts) - [src/llm/quix-agent.ts](https://github.com/clearfeed/quix/blob/HEAD/src/llm/quix-agent.ts) - [src/database/models/slack-workspace.model.ts](https://github.com/clearfeed/quix/blob/HEAD/src/database/models/slack-workspace.model.ts) - [src/lib/constants.ts](https://github.com/clearfeed/quix/blob/HEAD/src/lib/constants.ts) - [agent-packages/packages/github/src/schema.ts](https://github.com/clearfeed/quix/blob/HEAD/agent-packages/packages/github/src/schema.ts) - [src/llm/agent-evals/jira-agent/test-data.ts](https://github.com/clearfeed/quix/blob/HEAD/src/llm/agent-evals/jira-agent/test-data.ts) - [src/slack/views/app_home.ts](https://github.com/clearfeed/quix/blob/HEAD/src/slack/views/app_home.ts) - [README.md](https://github.com/clearfeed/quix/blob/HEAD/README.md)The Quix Slack agent is designed to understand user requests in natural language, interact with various business tools (like Jira, GitHub, HubSpot), and provide intelligent responses directly within Slack. This document outlines the end-to-end lifecycle of a user request, from the moment a message is sent in Slack to the final response delivered by the Quix bot. The entire process is orchestrated through a series of services, leveraging a Large Language Model (LLM) to plan and execute tasks.
The overall architecture is modular, with a core Nest.js application handling Slack events and LLM interactions, and separate agent-packages providing the specific tool integrations.
Sources: README.md
High-Level Request Flow
The following diagram illustrates the complete journey of a user request through the Quix system.
1. Event Ingestion from Slack
The lifecycle begins when a user interacts with the Quix bot in Slack, either by mentioning it in a channel (@Quix ...) or sending it a direct message. Slack sends an HTTP POST request to the Quix backend's /slack/events endpoint.
The SlackEventsHandlerService is the primary entry point for all incoming Slack events. It first determines the event type. For user messages, the most common type is event_callback.
Sources: src/slack/slack-events-handler.service.ts:40-47
Event Callback Handling
The handleEventCallback method routes the event based on its inner type. The key types for the request lifecycle are:
app_mention: When the bot is @-mentioned in a channel.message: For direct messages or other message-based interactions.
The diagram below shows the initial routing within the SlackEventsHandlerService.
2. Initial Handling and Authorization
Once an app_mention or message event is identified, the corresponding handler (handleAppMention or handleMessage) takes over.
Key steps in this phase include:
- Workspace Retrieval: The system fetches the
SlackWorkspaceconfiguration from the database using theteam_idfrom the event payload. This object contains API tokens, admin settings, and integration configurations. - Acknowledgement: For
app_mentionevents, the bot adds an:eyes:reaction to the message to signal that it is processing the request. - Authorization: The system performs critical authorization checks using methods on the
SlackWorkspacemodel:isChannelAuthorized(channelId): Checks if the bot is allowed to operate in the given channel (if a whitelist is configured).isUserAuthorized(userId): Checks if the user has permission to interact with the bot, based on the configuredQuixUserAccessLevel(EVERYONEorADMINS_ONLY).
If any check fails, the bot posts an informative error message and stops processing.
Sources: src/slack/slack-events-handler.service.ts:168-200, src/database/models/slack-workspace.model.ts:223-241
3. The Quix Agent Core Logic
If authorization succeeds, the event is passed to the LlmService, which utilizes the QuixAgent to process the request. The QuixAgent is the brain of the system, responsible for understanding the user's intent, planning a course of action, and executing it using the available tools.
The core method is processWithTools, which follows a three-step process: Tool Selection, Plan Generation, and Agent Execution.
Sources: src/llm/quix-agent.ts:19-30
Sequence of Agent Processing
This diagram shows the internal sequence of operations within the QuixAgent.processWithTools method.
Sources: src/llm/quix-agent.ts
3.1. Tool Selection
The first step is to determine which sets of tools are relevant to the user's query.
- The
toolSelectionmethod constructs a prompt for the LLM that includes descriptions of available tool categories (e.g., Jira, GitHub). - It uses a
DynamicStructuredToolnamedselectTool, which forces the LLM to output a structured response containing the chosentoolCategoriesand areason. - If the LLM determines no tools are needed (
'none'), the agent can return a direct response based on the LLM's general knowledge.
Sources: src/llm/quix-agent.ts:101-160
3.2. Plan Generation
Once tool categories are selected, the generatePlan method creates a multi-step plan for the agent to follow.
- It uses the
PLANNER_PROMPTto instruct the LLM to break down the user's request into an ordered list of tool calls. - The prompt includes the function signatures of all available tools from the selected categories.
- The LLM is constrained to produce a JSON output that adheres to the
PlanStepSchema, which defines each step as a tool call with a tool name and arguments.
Sources: src/llm/quix-agent.ts:162-202, src/lib/constants.ts:258-290
3.3. Agent Execution
With a plan in hand, the agent begins execution.
- The system uses
createReactAgentfrom LangChain, a ReAct (Reasoning and Acting) agent that can follow a plan, execute tools, and observe the results to inform subsequent steps. - The agent is provided with the generated plan as part of its system prompt.
- It iterates through the plan, invoking each tool with the specified arguments and collecting the output.
- The
QuixCallBackManagercan be used to track all tool calls made during execution.
Sources: src/llm/quix-agent.ts:79-91
4. Tool Definition
Tools are the functions that the agent can call to interact with external services. They are defined in separate packages within the agent-packages/ directory.
Each tool is defined with a Zod schema that specifies its name, description, and input arguments. This schema is used by the LLM to understand how to call the tool correctly.
For example, the GitHub tool for searching issues is defined with searchIssuesOrPullRequestsSchema.
// agent-packages/packages/github/src/schema.ts
export const baseSearchIssuesOrPullRequestsSchema = z.object({
type: z.enum(['issue', 'pr']),
keyword: z.string().nullish(),
reporter: z.string().nullish(),
assignee: z.string().nullish(),
status: z.enum(['open', 'closed']).nullish(),
// ... and other parameters
});
Sources: agent-packages/packages/github/src/schema.ts:8-35
This structured approach ensures that the agent provides valid arguments for each tool call. The test data files for agents like Jira and Slack provide excellent examples of how natural language queries map to specific tool calls and arguments.
Sources: src/llm/agent-evals/jira-agent/test-data.ts, src/llm/agent-evals/slack-agent/test-data.ts
5. Response Delivery
After the agent completes its execution, it returns a final, user-facing message.
- The
SlackEventsHandlerServicereceives this final string response from thellmService.processMessagecall. - It uses the
slackWorkspace.postMessagemethod to deliver the response to the user. - The message is posted in the original channel and, if applicable, in the same thread as the user's request (
replyThreadTs). - If any errors occur during processing (e.g., an
HttpException), they are caught, and a user-friendly error message is posted to Slack instead.
Sources: src/slack/slack-events-handler.service.ts:190-200, src/database/models/slack-workspace.model.ts:282-288
Summary
The request lifecycle in Quix is a robust, agent-driven process that effectively translates human language into machine-executable actions. It begins with event ingestion from Slack, proceeds through authorization and context building, and then enters the core QuixAgent logic. The agent's three-phase approach—Tool Selection, Plan Generation, and Execution—allows it to handle complex, multi-step requests by dynamically composing and running tool calls. Finally, the result is delivered back to the user in Slack, completing a seamless interactive loop.