Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
Agent Domain Model
| Status | Updated | Covered Files |
|---|
| 🟢 Stable | 2026-03-14 | features/agents/types.ts, features/agents/services/AgentQuotaService.ts, features/agents/services/AgentRunService.ts |
Overview
The agent domain model defines the entity structure for autonomous AI agent operations. An AgentRun is the top-level entity representing a single agent execution, containing an ordered list of AgentSteps and an optional AgentEscalation for human-in-the-loop workflows.
Entity Diagram
AgentDefinition (static config)
├─ id, name, description
├─ requiredFeature: Feature
├─ requiredPermissions: Permission[]
├─ allowedTools: string[]
├─ maxSteps, defaultCreditBudget
└─ category: AgentCategory
AgentRun (runtime instance)
├─ id, organizationId
├─ agentType, agentDefinitionId
├─ status: AgentRunStatus
├─ triggeredBy, triggeredByName
├─ permissions: Permission[] (snapshot)
├─ input / output
├─ steps: AgentStep[] (embedded)
├─ creditReservationId, creditsReserved, creditsConsumed
├─ totalInputTokens, totalOutputTokens
├─ startedAt, completedAt, durationMs
├─ error?: AgentRunError
├─ escalation?: AgentEscalation
└─ createdAt, updatedAt
AgentStep (embedded in AgentRun)
├─ id, runId, stepIndex
├─ toolName
├─ status: AgentStepStatus
├─ input / output
├─ creditsUsed, inputTokens, outputTokens, durationMs
├─ startedAt, completedAt
└─ error?: string
AgentEscalation (embedded in AgentRun)
├─ runId, stepId
├─ reason
├─ options: EscalationOption[]
├─ requiredPermission?: Permission
├─ resolvedBy, resolvedByName, resolution, resolvedAt
└─ escalatedAt
AgentRunStatus (State Machine)
type AgentRunStatus =
| 'queued' // Run created, waiting to start
| 'running' // Actively executing steps
| 'paused' // Temporarily paused (manual)
| 'awaiting_human' // Paused for human-in-the-loop decision
| 'completed' // All steps finished successfully
| 'failed' // Step failed with unrecoverable error
| 'cancelled'; // Manually cancelled by user
State transitions:
| From | To | Trigger |
|---|
| (new) | queued | startRun() — definition validated, credits reserved |
queued | running | Execution begins immediately after creation |
running | running | executeStep() — step completed, more steps remain |
running | awaiting_human | pauseRun() — escalation created |
running | completed | completeRun() — all steps done |
running | failed | failRun() — unrecoverable error |
running | cancelled | cancelRun() — user cancellation |
awaiting_human | running | resumeRun() — escalation resolved |
awaiting_human | cancelled | cancelRun() — user cancellation |
Terminal states: completed, failed, cancelled
AgentStepStatus
type AgentStepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
AgentDefinition
Static configuration that defines an agent’s capabilities and constraints. Stored in code (not Firestore) in agentDefinitions.ts.
| Field | Type | Description |
|---|
id | string | Unique identifier (e.g., compliance_checker) |
name | string | Human-readable name |
description | string | What the agent does |
requiredFeature | Feature | Entitlement gate (e.g., AGENT_MULTI_STEP) |
requiredPermissions | Permission[] | RBAC permissions the user must hold |
allowedTools | string[] | Tool names this agent can invoke |
maxSteps | number | Maximum steps per run |
defaultCreditBudget | number | Default credit reservation |
systemPrompt? | string | Optional LLM system prompt |
temperature? | number | Optional LLM temperature |
icon? | string | Lucide icon name for UI |
category | AgentCategory | UI grouping |
AgentCategory
type AgentCategory = 'compliance' | 'reporting' | 'grants' | 'finance' | 'journals' | 'general';
Tools are the atomic operations an agent can perform. Each tool wraps an existing service method.
interface AgentTool {
name: string;
description: string;
requiredPermissions: Permission[];
execute(input: Record<string, unknown>, context: AgentToolContext): Promise<AgentToolResult>;
}
interface AgentToolResult {
success: boolean;
output: Record<string, unknown>;
tokensUsed?: { input: number; output: number };
creditsUsed: number;
error?: string;
}
AgentToolContext
Passed to every tool invocation, providing the agent’s execution context:
interface AgentToolContext {
organizationId: string;
userId: string; // Triggering user
userPermissions: Permission[]; // Snapshot of user's RBAC at run start
agentRunId: string;
stepId: string;
}
AgentEscalation (Human-in-the-Loop)
When an agent encounters a decision requiring human judgment, it creates an escalation:
interface AgentEscalation {
runId: string;
stepId: string;
reason: string; // Why the agent is asking
options: EscalationOption[]; // Choices presented to the user
requiredPermission?: Permission; // Who can respond
resolvedBy?: string;
resolvedByName?: string;
resolution?: string; // The chosen option
resolvedAt?: string;
escalatedAt: string;
}
interface EscalationOption {
id: string;
label: string;
description?: string;
action: 'approve' | 'reject' | 'modify' | 'skip';
}
AgentRunError
interface AgentRunError {
message: string;
code?: string;
stepIndex?: number; // Which step failed
stepId?: string;
stack?: string;
}
AgentRunFilters (Query Interface)
Used by the UI to query runs:
interface AgentRunFilters {
organizationId: string;
agentType?: string;
status?: AgentRunStatus[];
triggeredBy?: string;
dateRange?: { start: string; end: string };
}
Credit Accounting on AgentRun
Each AgentRun tracks credit usage:
| Field | Description |
|---|
creditReservationId | Links to the CreditService reservation |
creditsReserved | Total credits reserved at start |
creditsConsumed | Sum of credits used across all steps |
Per-step credits are tracked in AgentStep.creditsUsed.
Token Accounting on AgentRun
| Field | Description |
|---|
totalInputTokens | Sum of all step input tokens |
totalOutputTokens | Sum of all step output tokens |
Per-step tokens: AgentStep.inputTokens, AgentStep.outputTokens.
Service Layer
Beyond the domain types above, three services manage agent runtime behavior:
AgentExecutionService
Orchestrates the full run lifecycle (start → step → complete/fail/cancel). See engineering/architecture/ai-engine-and-prompt-management.md for the detailed lifecycle documentation.
AgentQuotaService (Added March 2026)
Extends the generic QuotaService with agent-specific enforcement. Exported as singleton agentQuotaService.
| Method | Purpose |
|---|
validateRunStart() | Checks concurrent agent limit (per org, per tier), monthly run limit, and hourly rate limit before any run begins |
validateStepExecution() | Checks per-run step budget and token budget before each step executes |
getCreditUsageSummary() | Returns dashboard/billing summary of credit consumption |
Warning thresholds at 80% and 90% trigger QUOTA_WARNING events via EventBus for proactive alerting.
AgentRunService (Added March 2026)
Extends BaseService<AgentRun> to provide query/list capabilities for the agent_runs collection. Exported as singleton agentRunService.
| Method | Purpose |
|---|
listRuns(params) | Queries organizations/{orgId}/agent_runs with filtering by status, agentType, triggeredBy |
parseAgentRun() | Schema validation with Sentry error capture for malformed run documents |
useAgentRuns Hook
src/features/agents/hooks/useAgentRuns.ts provides React Query integration for the agent runs list. Returns:
runs[] — filtered agent run documents
loading, error — request state
summary — computed statistics: totalRuns, completedRuns, failedRuns, activeRuns, creditsConsumed, averageCreditCost, averageDurationMs
refetch() — manual refresh
Maintenance
Update this document when:
- Adding new fields to
AgentRun or AgentStep
- Introducing new agent categories
- Changing the state machine transitions
- Adding new escalation action types