Features
4.1. Conversations (convex/conversations/
)
- Definition: Conversations represent persistent chat threads where interactions between users and agents occur.
- Structure: Each conversation document in the
conversations
table (defined inconvex/schema.ts
) contains:title
: A user-editable string identifying the conversation (defaults to “New Conversation”).createdBy
: AnId<"users">
indicating which user initiated the conversation. This is used for ownership and access control.lastMessageTime
: A timestamp (number) updated whenever a new message is added, used primarily for sorting conversations in the sidebar list.
- Lifecycle: Created via the
create
mutation (convex/conversations/mutations.ts
), listed vialistMine
query, updated viaupdateMine
, and removed viaremoveMine
. Access control ensures users can only interact with conversations they created (ensureICanAccessConversation
helper inconvex/conversations/model.ts
).
4.2. Agents (convex/agents/
)
- Definition: Agents are the AI entities that participate in conversations alongside users. They have defined characteristics and capabilities.
- Types: Defined by the
kind
field in theagents
table (convex/agents/schema.ts
):user_agent
: Created and managed by users. They have personalities, descriptions, and selectable tools.system_agent
: Internal agents performing specific backend roles. Currently, only thetriage
agent exists (systemAgentKind
field). System agents typically cannot be directly managed or removed from conversations by users.
- Structure: Common properties include:
name
,description
,personality
: User-defined text fields shaping the agent’s identity and behavior.avatarUrl
: URL for the agent’s visual representation (AgentAvatar.tsx
), generated using DiceBear (createAgentAvatarUrl
inconvex/agents/model.ts
).tools
: An array of strings representing the names (AgentToolName
) of the tools the agent is equipped to use (defined inshared/tools.ts
).lastActiveTime
: Timestamp indicating the last time the agent was involved in an action.createdBy
(Id<"users">
): Only present foruser_agent
, linking it to its creator.
- Management: Users create agents (
create
mutation), which often start based on templates (shared/predefinedAgents.ts
). They can list (listMine
), view (getMine
), update (updateMine
), and delete (removeMine
) their own agents.
4.3. Participants (convex/conversationParticipants/
)
- Definition: Participants act as the crucial link connecting specific
users
oragents
to specificconversations
. A user or agent must be a participant in a conversation to send or receive messages within it. - Structure: Defined in the
conversationParticipants
table (convex/conversationParticipants/schema.ts
). Key fields:conversationId
: Links to the relevant conversation.kind
: Either"agent"
or"user"
.agentId
oruserId
: The ID of the linked agent or user, depending on thekind
.status
: Indicates the agent’s current activity (inactive
orthinking
). Used for UI feedback (ThinkingIndicator.tsx
).addedAt
: Timestamp when the participant joined.isRemoved
: Boolean flag to handle participant removal without deleting the record (allows potentially re-joining).
- Management: Participants are added when a user creates a conversation (
addUser
inconvex/conversations/model.ts
), when an agent is explicitly added (addAgent
mutation inconvex/conversationParticipants/mutations.ts
or via theaddParticipantToConversation
tool), or implicitly when a system agent like Triage joins (joinTriageAgentToConversationIfNotAlreadyJoined
inconvex/conversations/model.ts
). They can be removed (removeParticipant
mutation). Backend logic often fetches participant details (getParticipantUserOrAgent
inconvex/conversationParticipants/model.ts
).
4.4. Messages (convex/conversationMessages/
)
- Definition: Messages are the individual units of communication within a conversation.
- Types (
kind
field): Defined inconvex/conversationMessages/schema.ts
:participant
: A message sent by either a user or an agent who is a participant in the conversation. Contains anauthorParticipantId
field linking to the specificconversationParticipants
entry.system
: A message generated by the backend system to inform users about events (e.g., participant joins/leaves, tool usage, errors). Does not have anauthorParticipantId
. Can contain optional structured data in themeta
field.
- Structure: Common fields include:
conversationId
: Links the message to its conversation.content
: The text content of the message. For participant messages, this content may include mentions._creationTime
: Automatically added by Convex, used for ordering messages.
- Lifecycle: Created via mutations (
sendFromMe
,sendFromAgent
,sendSystemMessage
). Processed asynchronously by theprocessMessage
action (convex/conversationMessages/internalActions.ts
) if it’s a participant message. Displayed chronologically in the UI (ChatArea.tsx
,ChatMessage.tsx
).
4.5. Mentions (shared/mentions.ts
)
- Definition: A specific syntax (
@[DisplayName](kind:ID)
) embedded within message content to reference a particular user or agent. - Purpose:
- Directing Communication: Signals that a message is intended for the mentioned participant(s).
- Triggering Actions: When an agent is mentioned, it triggers the
agentReplyToMessage
AI workflow for that agent. Messages without mentions trigger thetriageMessage
workflow.
- Syntax Examples:
- Agent:
@[Support Bot](agent:a1b2c3d4)
- User:
@[Alice](user:x9y8z7w6)
- Agent:
- Handling:
- Frontend: The
react-mentions
library inChatInput.tsx
provides the user interface for creating mentions. - Backend: The
parseMentionsFromMessageContent
function (shared/mentions.ts
) extracts references from thecontent
string within theprocessMessage
action (convex/conversationMessages/internalActions.ts
). - Shared: Utility functions (
createMentionString
,splitMessageContent
) exist inshared/mentions.ts
for consistent handling across frontend and backend.
- Frontend: The
4.6. AI Logic (convex/ai/
)
- Core Workflow: Orchestrated primarily through Convex Actions (
agentReplyToMessage.ts
,triageMessage.ts
). - Triage Agent (
triageMessage.ts
): Handles participant messages without mentions. Its goal is not to answer directly but to use its tools (likelistAgents
,listConversationParticipants
,messageAnotherAgent
,addParticipantToConversation
) to decide which agent(s) should handle the message and then mentions them, triggering their reply workflow. - Agent Reply (
agentReplyToMessage.ts
): Handles messages where a specific agent was mentioned. This agent gathers conversation history, combines it with its specific instructions and personality, uses its assigned tools if necessary, and generates a response. - Instructions (
instructions.ts
): Provides the core system prompts that guide the AI’s behavior, tailored for either the triage task or the general agent reply task. Includes details about the agent itself, the message author, and the conversation context. - History & Context (
history.ts
,messages.ts
): Logic for fetching recent relevant messages and formatting them (including author information) into the structure expected by the AI model (e.g.,CoreMessage[]
from theai
SDK). - Tools (See below): The mechanism by which agents perform actions beyond text generation.
- State Management (
utils.ts
): Helper functions manage thestatus
field (thinking
/inactive
) of agent participants to provide UI feedback. Includes error handling (handleAgentError
) and consistent ways to send system messages (sendSystemMessageToConversation
). - AI SDK (
ai
,@ai-sdk/openai
): The Vercel AI SDK is used within actions to simplify interactions with the OpenAI API, handling prompt construction, tool definition, tool calling, response parsing, and streaming (although streaming isn’t explicitly used for message responses here, the SDK handles the interaction flow).
4.7. Tools (shared/tools.ts
, convex/ai/tools.ts
)
- Definition: Pre-defined functions that AI agents can invoke to interact with the application’s backend, external APIs, or perform specific tasks. Analogous to function calling in some AI models.
- Structure (
shared/tools.ts
): Each tool has:name
: A unique identifier.description
: A natural language description telling the AI when to use the tool.parameters
: Azod
schema defining the arguments the tool expects, including descriptions for each parameter. This allows the AI SDK to validate arguments provided by the AI model.
- Implementation (
convex/ai/tools.ts
): The actual code for each tool is implemented within a Convex action using thetool
helper from theai
SDK. This code performs the desired action (e.g., callingctx.runQuery
,ctx.runMutation
, fetching from Exa/Resend). - Availability:
alwaysIncludedTools
: A subset of tools available to all agents (including system agents).userChoosableToolDefinitions
: Tools that can be assigned touser_agent
s via the UI (AgentTools.tsx
).- An agent’s final toolset is the combination of
alwaysIncludedTools
and the specific tools assigned to it (createToolsForAgent
inconvex/ai/tools.ts
).
- Execution Flow:
- AI model decides to use a tool based on the prompt and its tool definitions.
- AI model generates the tool name and arguments.
- AI SDK intercepts this, validates arguments against the Zod schema.
- AI SDK calls the corresponding
execute
function inconvex/ai/tools.ts
. - The
execute
function runs (potentially calling other Convex functions or external APIs). - The result of
execute
is returned to the AI SDK. - AI SDK sends the tool result back to the AI model.
- AI model uses the result to generate its final text response.
4.8. Authentication (convex/auth.ts
, @convex-dev/auth
)
- Library: Relies on the
@convex-dev/auth
community library, which simplifies integrating various authentication methods with Convex. - Integration: Works seamlessly with Convex’s built-in user identity system. Successfully authenticated users map to records in the
users
table (part ofauthTables
inconvex/schema.ts
). - Providers (
convex/auth.config.ts
): Configured to support GitHub OAuth and Email/Password flows. The configuration includes necessary domain/application IDs and potential validation logic (like password strength checks, though the current one is permissive). - Server-Side (
convex/auth.ts
): Initializes the auth system, providing backend functions (auth
,signIn
,signOut
,store
,isAuthenticated
) used internally and potentially by HTTP endpoints. - Client-Side (
@convex-dev/auth/react
): Provides React hooks (useConvexAuth
for checking auth state,useAuthActions
for triggering sign-in/out) used in components likeSignOutButton.tsx
,SignInWithGithub.tsx
,SignInWithPassword.tsx
, andApp.tsx
. - HTTP Endpoints (
convex/http.ts
): The auth library registers necessary HTTP routes (e.g., for OAuth callbacks, password sign-in/up requests) on the Convex backend.