Skip to content

Frona is a single application with a Rust backend and a Next.js frontend, backed by an embedded SurrealDB database.

Engine (Rust backend)

The engine is the core of the platform. It handles:

  • HTTP API: built on Axum, serves REST endpoints and SSE streams
  • Agent orchestration: loads agent configs, manages tool loops, coordinates delegation
  • Tool execution: runs tools server-side, manages browser sessions, sandboxes CLI/Python/Node.js commands
  • Authentication: JWT-based auth with cookie and header support, optional SSO via OpenID Connect
  • Database: SurrealDB embedded with RocksDB storage
  • Scheduling: background task runner for scheduled tasks, heartbeats, compaction, and maintenance
  • Inference: multi-provider LLM abstraction with fallback and retry support (via rig-core)
  • App management: agent-deployed applications with sandboxed execution and health monitoring

Key modules

ModulePurpose
api/HTTP routes, middleware, request/response types
agent/Agent models, service, tasks, prompt loading
app/Agent-deployed application lifecycle and sandboxing
auth/Authentication, JWT, SSO
call/Voice call management
chat/Chat sessions, messages, streaming
contact/Contact management
credential/Vault providers, credential storage, grants
inference/LLM provider abstraction, tool loop
memory/Fact storage, compaction
notification/User notifications
scheduler/Background task execution, heartbeats
space/Space context management
storage/File storage, workspaces, virtual paths
tool/Tool implementations, registry, sandbox

Frontend (Next.js)

The frontend is a Next.js application using the App Router with static export. It provides:

  • Chat interface with real-time streaming
  • Agent management and configuration UI
  • Workspace and space navigation
  • File attachments and tool result rendering
  • App management and approval flows
  • Settings and vault management
  • Authentication flows (login, register, SSO)
  • Setup wizard for first-time configuration

Key libraries

  • Next.js 16 with React 19 and TypeScript
  • Tailwind CSS for styling
  • Shiki for syntax highlighting
  • SSE client for real-time message streaming

Database (SurrealDB)

SurrealDB runs embedded inside the engine process. It uses RocksDB as the storage backend, so there's no separate database server to manage.

Tables

TableStores
userUser accounts
agentAgent definitions and configuration
chatChat sessions
messageChat messages
taskTasks (direct, delegated, scheduled)
spaceSpaces and their context
memoryMemory scopes
memory_entryIndividual memory facts
credentialLocally stored credentials
vault_connectionExternal vault provider connections
vault_grantCredential access grants
vault_access_logCredential access audit trail
appDeployed applications
tool_callTool call records
keypairJWT signing keypairs (encrypted at rest)
api_tokenPersonal access tokens
oauth_identitySSO identity links
notificationUser notifications
contactContacts
callVoice call records
runtime_configRuntime configuration

Data flow

A typical request flows like this:

  1. User sends a message through the frontend
  2. Frontend makes a POST to the engine API
  3. Engine loads the agent config, conversation history, and memory
  4. Engine sends the prompt to the configured LLM provider
  5. LLM response streams back. If it includes tool calls, the engine executes them in the agent's sandbox.
  6. Tool results feed back into the LLM for the next iteration (the tool loop)
  7. Final response tokens stream to the frontend via SSE
  8. Messages are persisted to SurrealDB

Configuration system

The engine loads configuration from a YAML file and environment variable overrides. Environment variables use the FRONA_ prefix with underscore-separated paths (e.g., FRONA_SERVER_PORT maps to server.port).

Prompts are loaded from .md files in the shared config directory, not hardcoded. This makes it easy to customize agent behavior without modifying code.