SPEC 018 — Equanaut AI Assistant
| Field | Value |
|---|---|
| Status | DRAFT |
| Priority | P1 — Core Platform |
| Backend | equa-server/modules/agent/ |
| Frontend | equa-web/src/modules/equanaut/ |
| Endpoints | equa-server/modules/agent/src/endpoints/agent-endpoints.ts |
| Model | claude-sonnet-4-20250514 (default, configurable via EQUANAUT_MODEL / AGENT_MODEL) |
| Env | ANTHROPIC_API_KEY (required), AGENT_ENABLED (optional kill switch) |
1. Feature Purpose
Equanaut is the AI assistant embedded in the Equa platform. It provides a conversational interface for users to query and manage their organizations, cap tables, members, documents, and equity plans. The assistant uses Claude with tool-calling to execute read and write operations on the user’s behalf, with a security layer that requires explicit confirmation for write/destructive operations. A secondary onboarding pipeline uses the same AI infrastructure to analyze uploaded documents and set up organizations for new users.2. Current State (Verified)
2.1 Agent Service (Backend Core)
| Detail | Value |
|---|---|
| File | equa-server/modules/agent/src/agent-service.ts |
| Class | AgentService |
| SDK | @anthropic-ai/sdk |
| Model | Configurable, default claude-sonnet-4-20250514 |
| Max tokens | Configurable, default 4096 |
| Components | ContextAssembler, ToolExecutor, Guardrails, AuditLogger, PermissionProxy |
| Message flow | 1. Permission check → 2. Context assembly → 3. Tool filtering by permissions → 4. Claude API call → 5. Tool execution loop → 6. Response |
2.2 Tool System
| Detail | Value |
|---|---|
| File | equa-server/modules/agent/src/tools/definitions.ts |
| Categories | ToolCategory.Read, ToolCategory.Write, ToolCategory.Destructive |
| Confirmation | Write tools require single confirmation; Destructive tools require double confirmation; Read tools execute immediately |
| Permission filtering | filterToolsByPermissions() — only shows tools the user has permission for |
| Tool catalogs | catalog/organization.ts, catalog/members.ts, catalog/captable.ts, catalog/documents.ts, catalog/plans.ts, catalog/roles.ts |
| Executor | equa-server/modules/agent/src/tools/executor.ts — ToolExecutor.execute() |
| Category | Tools | Confirmation |
|---|---|---|
| Organization | listOrganizations, getOrganization, getOrganizationDashboard, updateOrganization | Read: none, Write: single |
| Members | listMembers, getMember, addMember, updateMember, removeMember | Read: none, Write: single, Destructive: double |
| Cap Table | getCapTable, getSecurityTypes, createSecurityType, createShareholding | Read: none, Write: single |
| Documents | listDocuments, getDocument, createFolder, moveDocument | Read: none, Write: single |
| Plans | listPlans, getPlan, createPlan, createGrant | Read: none, Write: single |
| Roles | listRoles, getRole, createRole, updateRole | Read: none, Write: single |
2.3 Security & Guardrails
| Detail | Value |
|---|---|
| File | equa-server/modules/agent/src/security/guardrails.ts |
| Rate limits (defaults) | 30 tool calls/min, 10 write ops/min, 5 destructive ops/hour |
| Confirmation expiry | 5 minutes |
| Confirmation states | claimed flag prevents race conditions (TOCTOU protection) |
| Permission proxy | equa-server/modules/agent/src/security/permission-proxy.ts — validates org access and retrieves user permissions |
| Audit logging | Every tool call logged with user, org, tool name, arguments, result status, execution time |
2.4 Context Assembly
| Detail | Value |
|---|---|
| File | equa-server/modules/agent/src/context/assembler.ts |
| Class | ContextAssembler |
| Builds | UserContext (id, email, name, org list) + OrganizationContext (id, name, type, stats) + ContextSummaries (cap table, members, documents) |
| Summarizer | equa-server/modules/agent/src/context/summarizer.ts — converts context to text for system prompt |
2.5 Pending Confirmations
| Detail | Value |
|---|---|
| Storage | In-memory Map<string, PendingConfirmation> on AgentService |
| Confirmation flow | 1. Tool requires confirmation → 2. Store pending + return confirmation_required → 3. User confirms/cancels via /agent/confirm → 4. Execute or abort |
| Expiry cleanup | cleanupExpiredConfirmations() runs on each confirmAction() call |
| Persistence caveat | In-memory only — lost on server restart (noted as TODO) |
2.6 Onboarding Pipeline
| Detail | Value |
|---|---|
| Files | equa-server/modules/agent/src/onboarding/onboarding-service.ts, onboarding-repository.ts, organization-builder.ts, context-analyzer.ts, clarification-engine.ts, file-processor.ts |
| Parsers | parsers/pdf-parser.ts, parsers/excel-parser.ts |
| Status flow | pending_signup → pending_setup → setting_up → ready → first_login → completed |
| Analysis | Extracts entities (founders, investors, employees), equity info, security types, confidence scores |
| Clarification | Generates questions when confidence is below threshold; supports iterative Q&A |
| Showcase | Presents extracted data for user review with inline editing (corrections) |
2.7 System Prompt
| Detail | Value |
|---|---|
| Identity | ”You are Equanaut, an AI assistant for the Equa platform” |
| Context injection | User name, org name, org stats, cap table summary, member summary, document summary |
| Guidelines | Read ops: proactive data gathering. Write ops: explain before execute, require confirmation. Destructive: extra caution, impact explanation. |
| Constraints | Never guess data, respect permissions, USD default, YYYY-MM-DD dates, precise share numbers |
2.8 Frontend API Configuration
| Detail | Value |
|---|---|
| File | equa-web/src/modules/equanaut/services/api/config.ts |
| Base URL | window.__EQUANAUT_CONFIG__.apiUrl → EQUANAUT_API_URL → /equanaut-api (fallback) |
| Model | window.__EQUANAUT_CONFIG__.model → EQUANAUT_MODEL → claude-sonnet-4-20250514 |
| Webpack proxy | /equanaut-api → localhost:19792 or Hetzner server |
| Timeout | 60,000ms |
| Retry | 2 attempts, 1s initial delay, 10s max, 1.5x timeout multiplier |
3. Data Model
AgentConfig
| Field | Type | Default |
|---|---|---|
| apiKey | string | ANTHROPIC_API_KEY env |
| model | string | claude-sonnet-4-20250514 |
| maxTokens | number | 4096 |
| maxToolCallsPerMinute | number | 30 |
| maxWriteOperationsPerMinute | number | 10 |
| maxDestructivePerHour | number | 5 |
| confirmWriteOperations | boolean | true |
ToolDefinition
| Field | Type | Description |
|---|---|---|
| name | string | Tool identifier |
| description | string | Human-readable description |
| category | ToolCategory | read, write, or destructive |
| inputSchema | ToolInputSchema | JSON Schema for tool parameters |
| requiredPermission | string? | Permission needed to access tool |
| confirmationRequired | boolean | Auto-true for write/destructive |
| doubleConfirmRequired | boolean? | Auto-true for destructive |
PendingConfirmation (in-memory)
| Field | Type | Description |
|---|---|---|
| id | string | UUID |
| toolCall | ToolCall | Tool name + input |
| userId | Uuid | Requesting user |
| organizationId | Uuid | Target organization |
| conversationId | string | Chat session ID |
| claudeMessages | any[] | Message history for continuation |
| priorToolResults | any[] | Results from batch tools before this confirmation |
| createdAt | Date | |
| expiresAt | Date | 5 minutes from creation |
| claimed | boolean | TOCTOU protection |
AgentAuditLog
| Field | Type | Description |
|---|---|---|
| type | string | Always agent_action |
| user | Uuid | Acting user |
| organization | Uuid | Target organization |
| data.tool | string | Tool name |
| data.arguments | object | Tool input |
| data.result | string | success, failed, or cancelled |
| data.conversationId | string | Chat session |
| data.timestamp | Date | |
| data.executionTimeMs | number? | Execution duration |
OnboardingContext
| Field | Type | Description |
|---|---|---|
| id | string | UUID |
| userId | Uuid? | Linked after signup |
| string | User email | |
| initialPrompt | string | Free-text describing the organization |
| status | OnboardingStatus | Status enum |
| setupResult | OnboardingSetupResult? | Organization build result |
| analysisResult | OnboardingAnalysisResult? | AI analysis output |
| clarifyingQuestions | ClarifyingQuestion[]? | Generated questions |
| confidenceScores | object? | Per-category confidence |
| createdAt / updatedAt / expiresAt | Date | Timestamps |
4. API Endpoints
Chat & Tools
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/v1/agent/status | None | Health check — returns { enabled: true, version: '1.0.0' } |
| POST | /api/v1/agent/chat | Session + canViewOrganization | Send message, receive response or confirmation request |
| POST | /api/v1/agent/confirm | Session | Confirm or cancel a pending action |
| GET | /api/v1/organization/:organization/agent/context | Session + canViewOrganization | Get assembled context for an organization |
| GET | /api/v1/organization/:organization/agent/tools | Session + canViewOrganization | List available tools filtered by user permissions |
Onboarding (Authenticated)
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/v1/agent/onboarding/link | Session | Link authenticated user to pre-existing onboarding context |
| POST | /api/v1/agent/onboarding/setup | Session | Trigger organization setup from onboarding context |
| GET | /api/v1/agent/onboarding/first-login | Session | Check for pending onboarding on first login |
| POST | /api/v1/agent/onboarding/complete | Session | Mark onboarding as completed |
| POST | /api/v1/agent/onboarding/analyze | Session | Trigger AI analysis of onboarding context |
| POST | /api/v1/agent/onboarding/build | Session | Build organization from analysis results |
| POST | /api/v1/agent/onboarding/clarify | Session | Submit answer to clarifying question |
| POST | /api/v1/agent/onboarding/correct | Session | Submit correction to showcase item |
Onboarding (Public)
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/v1/agent/onboarding/create | Public | Create onboarding context (pre-registration) |
| GET | /api/v1/agent/onboarding/:id | Public | Retrieve onboarding context |
| GET | /api/v1/agent/onboarding/analysis-status/:id | Public | Check analysis completion status |
| GET | /api/v1/agent/onboarding/questions/:id | Public | Get clarifying questions |
| GET | /api/v1/agent/onboarding/showcase/:id | Public | Get showcase data for review |
5. Frontend Components
Module: equa-web/src/modules/equanaut/
Core Components:
| Component | File | Purpose |
|---|---|---|
EquanautSidebar | components/EquanautSidebar.tsx | Main sidebar container for the assistant |
ChatContainer | components/ChatContainer.tsx | Chat message list with scroll management |
ChatInput | components/ChatInput.tsx | Message input with send button |
ChatMessage | components/ChatMessage.tsx | Individual message bubble (user/assistant) |
Header | components/Header.tsx | Sidebar header with title and controls |
StatusBar | components/StatusBar.tsx | Connection/loading status display |
MarkdownRenderer | components/MarkdownRenderer.tsx | Renders assistant markdown responses |
Icons | components/Icons.tsx | SVG icon components |
| Component | File | Purpose |
|---|---|---|
ToolExecutionPanel | components/ToolExecutionPanel.tsx | Displays executing tool steps with status indicators |
ConfirmationDialog | components/ConfirmationDialog.tsx | Confirm/cancel dialog for write operations |
ConfidenceBadge | components/ConfidenceBadge.tsx | Confidence score indicator |
| Component | File | Purpose |
|---|---|---|
ConversationList | components/ConversationList.tsx | List of past conversations |
ConversationItem | components/ConversationItem.tsx | Single conversation entry |
MessageFeedback | components/MessageFeedback.tsx | Thumbs up/down feedback on messages |
| Component | File | Purpose |
|---|---|---|
OnboardingFlow | components/OnboardingFlow.tsx | AI-guided onboarding experience |
MVPShowcase | components/MVPShowcase.tsx | Preview of extracted organization data |
ShowcaseItem | components/ShowcaseItem.tsx | Individual item with confidence and edit |
InlineEditor | components/InlineEditor.tsx | In-place editing for corrections |
ClarifyingQuestionsFlow | components/ClarifyingQuestionsFlow.tsx | Q&A flow for missing information |
ClarifyingQuestion | components/ClarifyingQuestion.tsx | Single question with suggested answers |
| Service | File | Purpose |
|---|---|---|
agentService | services/api/agent/agent-service.ts | API client for all agent endpoints (chat, confirm, context, tools, onboarding) |
ActionExecutor | services/ActionExecutor.ts | Client-side action execution orchestration |
chat/messages | services/api/chat/messages.ts | Message formatting utilities |
| Provider | File | Purpose |
|---|---|---|
EquanautProvider | context/EquanautProvider.tsx | Top-level provider for Equanaut state |
AgentContextProvider | context/AgentContextProvider.tsx | Agent context (org, tools) management |
PageContextProvider | context/PageContextProvider.tsx | Current page context for the agent |
FormRegistry | context/FormRegistry.tsx | Tracks active forms for context-aware assistance |
| Hook | File | Purpose |
|---|---|---|
useAgentChat | hooks/useAgentChat.ts | Core chat state management (messages, loading, pending actions, conversation ID) |
useChat | hooks/useChat.ts | Chat session management |
useMessageFeedback | hooks/useMessageFeedback.ts | Feedback state for message ratings |
useClickOutside | hooks/useClickOutside.ts | Click-outside handler for closing sidebar |
6. Business Rules
- Agent availability is gated by
ANTHROPIC_API_KEY— if absent,isAgentEnabled()returns false and all endpoints return disabled status. Can also be explicitly disabled viaAGENT_ENABLED=false. - Permission enforcement: Users can only access tools they have permissions for.
filterToolsByPermissions()strips unauthorized tools from the Claude tool list. - Organization access:
permissionProxy.hasOrganizationAccess()is checked before any chat request. Unauthorized users receive an error. - Confirmation flow: All write operations require user confirmation before execution. Destructive operations require double confirmation. Confirmations expire after 5 minutes.
- Rate limiting: Per user-org pair — max 30 tool calls/min, 10 write ops/min, 5 destructive ops/hour (configurable via env).
- Audit trail: Every tool execution is logged with user, org, tool, arguments, result, and timing.
- Context injection: The system prompt includes organization stats, cap table summary, member summary, and document summary for grounded responses.
- Batch tool execution: When Claude requests multiple tools, read-only tools execute immediately. The first write/destructive tool in a batch triggers confirmation, preserving prior tool results for continuation.
- Onboarding public endpoints:
create,get context,analysis-status,questions, andshowcaseare public (pre-registration). All mutation endpoints require authentication. - Onboarding expiry: Contexts have an
expiresAtfield; expired contexts transition toexpiredstatus. - Frontend retry: API calls retry up to 2 times with exponential backoff (1s initial, 10s max, 1.5x multiplier).
7. Acceptance Criteria
- User can open the Equanaut sidebar and send a chat message
- Agent responds with accurate information about the user’s organization
- Read-only tool calls execute without confirmation prompts
- Write operations display a confirmation dialog before execution
- Destructive operations display a double-confirmation dialog
- Confirmed actions execute and return results to the conversation
- Cancelled actions abort cleanly with a cancellation message
- Confirmation requests expire after 5 minutes
- Rate-limited requests return a clear error with retry timing
- Users without organization access receive a permission error
- Tool list is filtered to only show tools the user has permission for
- Onboarding flow: user can describe their company and get an AI-built organization
- Onboarding analysis extracts entities, equity info, and security types with confidence scores
- Clarifying questions flow works for ambiguous inputs
- Showcase displays extracted data with inline editing for corrections
- Agent audit log captures all tool executions
- Agent gracefully handles Anthropic API errors
8. Risks
| Risk | Impact | Mitigation |
|---|---|---|
| Pending confirmations stored in memory | Lost on server restart, potential data loss if user confirmed mid-restart | Persist to database (noted as TODO in source) |
| Claude model costs per conversation | Uncontrolled spend with active users | Rate limiting exists; add per-user/per-org spend caps |
| Tool execution errors not rolled back | Partial state changes if multi-tool operation fails partway | Implement compensating transactions for critical write operations |
| Context assembly queries full DB on each message | Performance degradation with large organizations | Cache context with TTL; use buildWithSummaries (already summarizes) |
| Onboarding analysis confidence may be low | Users may get incorrect organization setup | Showcase review with inline corrections + clarifying questions mitigate this |
| Webpack proxy to localhost:19792 assumes local dev or Hetzner | Production deployment requires proper proxy/routing configuration | Document production deployment path with reverse proxy |
| No conversation persistence | Chat history lost on page refresh | Implement conversation storage (backend or localStorage) |
window.__EQUANAUT_CONFIG__ global injection | Configuration scattered across webpack, env vars, and runtime globals | Consolidate to a single configuration source |