Convex Server Functions & Mutations
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Convex Server Functions and Mutations serve as the backend logic layer for the Abee platform, providing a real-time serverless environment for managing synthetic user testing data. These functions handle the persistence of test runs, persona configurations, real-time agent browsing events, and final analysis results. By utilizing Convex, the system ensures that data is stored in a structured, type-safe manner and can be reactively queried by the frontend to provide live updates of agent progress.
The architecture separates concerns into Queries, which are read-only operations used for fetching data like run statuses or aggregated results, and Mutations, which are atomic operations responsible for modifying the database state, such as inserting new agent events or updating a test run's completion status.
Sources: convex/README.md:1-5, convex/schema.ts:1-5, plan.md:118-123
Function Types and Architecture
The project utilizes several specialized types of Convex functions to manage different aspects of the server-side lifecycle.
Queries and Mutations
- Queries: Public functions used to read data. They are reactive, meaning the client updates automatically when the underlying database changes.
- Mutations: Public functions used to write or modify data. Convex guarantees atomicity for all writes within a single mutation, preventing inconsistent data states.
- Internal Functions: Both queries and mutations can be defined as "internal," making them accessible only from other Convex functions rather than the public client API.
Sources: convex/_generated/server.d.ts:25-72, convex/_generated/server.d.ts:161-167
Function Execution Flow
The following diagram illustrates how a client interacts with Convex functions to execute a mutation and receive real-time updates through a query.
Visual representation of the interaction between the client and Convex server-side logic.
Sources: convex/README.md:12-40, convex/_generated/server.d.ts:161-167
Data Models and Schema
The server functions operate on a strictly defined schema comprising four primary tables. These tables track the lifecycle of a synthetic testing session from configuration to final report generation.
Table Schema Summary
| Table | Description | Primary Indexes |
|---|---|---|
runs | Tracks high-level test run metadata (URL, goal, status). | Default _id |
personas | Stores the 19-trait configuration for each AI agent. | by_run |
agent_events | A real-time stream of actions taken by autonomous agents. | by_run, by_run_persona |
results | Aggregated data including conversion rates and friction points. | by_run |
Sources: convex/schema.ts:50-136, plan.md:125-144
The Persona Configuration Model
Mutations involving the personas table must adhere to a comprehensive validator. This model ensures that every AI persona has the necessary psychological and demographic traits for realistic simulation.
const personaConfigValidator = {
age: v.number(),
tech_literacy: v.number(),
patience: v.number(),
decision_style: v.union(
v.literal("impulsive"),
v.literal("methodical"),
v.literal("cautious"),
v.literal("research_heavy")
),
behavioral_rules: v.array(v.string()),
identity_prompt: v.string(),
};
Sources: convex/schema.ts:4-48
Real-time Event Streaming
One of the most critical roles of Convex server functions in Abee is handling the agent_events stream. As the AgentRunner navigates a site using the Browser Use SDK, it invokes mutations to record every step.
Agent Event Logic
Each event captures the agent's internal state, including:
- Psychological State: Booleans for
is_confusedandis_frustrated. - Navigation Details:
page_url,next_goal, andactionstaken. - Lifecycle Status: Updates the agent's current state (e.g.,
navigating,abandoned,converted).
Sources: convex/schema.ts:89-110, README.md:105-110
The flow of data from an autonomous browser agent into the Convex database.
Sources: convex/schema.ts:89-110, convex/_generated/server.d.ts:161-167
Implementation Examples
Implementation follows a pattern of defining arguments with validators and providing a handler that receives the context (ctx).
Mutation Implementation
A mutation is used to insert data, such as a new test run.
// Example based on project structure
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const createRun = mutation({
args: { url: v.string(), goal: v.string() },
handler: async (ctx, args) => {
const runId = await ctx.db.insert("runs", {
url: args.url,
goal: args.goal,
status: "configuring",
created_at: Date.now(),
});
return runId;
},
});
Sources: convex/README.md:43-63, convex/schema.ts:74-87
Query Implementation
A query fetches data, such as all events for a specific persona within a run.
// Example based on project structure
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getEventsByPersona = query({
args: { runId: v.id("runs"), personaIndex: v.number() },
handler: async (ctx, args) => {
return await ctx.db
.query("agent_events")
.withIndex("by_run_persona", (q) =>
q.eq("run_id", args.runId).eq("persona_index", args.personaIndex)
)
.collect();
},
});
Sources: convex/README.md:11-33, convex/schema.ts:111-112
Summary
Convex Server Functions & Mutations provide the backbone for Abee's data-driven simulation engine. By enforcing a strict schema and utilizing atomic mutations, the system maintains high integrity for complex persona data and real-time event logs. This architecture allows the platform to scale from single-agent smoke tests to parallel execution of 1000 synthetic users while providing a live, reactive dashboard for UX researchers.
Sources: README.md:280-290, plan.md:11-20