Laya Documentation
Everything you need to set up, configure, and master Laya.
Overview
Laya is an open-source, local-first AI command center that intercepts notifications from your professional tools (Gmail, Slack, Jira, GitHub, Calendar, and more), processes them through a multi-stage AI pipeline, and delivers ready-to-approve Action Cards to your desktop.
By the time you open Laya, the AI has already researched context, drafted responses, classified priorities, and packaged everything into one-click actions.
Architecture at a glance: Laya consists of three components — the Engine (Python/FastAPI backend), the UI (Svelte 5/Tauri desktop app), and n8n (local Node.js integration gateway). All data stays on your machine.
Prerequisites
- macOS, Windows, or Linux desktop
- Node.js 18+ — required for n8n (the integration gateway). n8n is installed automatically as a local npm module.
- Python 3.11+ — for the Laya Engine (bundled in releases)
- An LLM provider — either a cloud API key (Anthropic, OpenAI, Google, OpenRouter) or a self-hosted model server like Ollama, LM Studio, or any OpenAI-compatible endpoint. No API key needed for local models.
- OS Keychain access — macOS Keychain, Windows Credential Manager, or Linux Secret Service (for storing API keys securely)
Installation
Option A: Download Release
Download the latest release from GitHub. The desktop app bundles the Engine and automatically installs n8n on first launch.
Option B: Build from Source
# Clone the repository
git clone https://github.com/your-org/laya.git
cd laya
# One-time setup (installs Python deps, Node deps, and n8n)
./scripts/setup-dev.sh
# Run the app (starts Engine + Tauri dev server + n8n)
./scripts/dev.sh
If you prefer to run each step manually instead of using the scripts above:
# Install n8n locally
mkdir -p ~/.laya/n8n_module ~/.laya/n8n
npm install --prefix ~/.laya/n8n_module n8n
# Start the Engine
cd engine
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m laya.main
# Start the UI (in a separate terminal)
cd ui
npm install
npm run dev
First Run
When Laya starts for the first time, it automatically:
- Creates the
~/.laya/directory with default config files - Detects Node.js and installs n8n locally (into
~/.laya/n8n_module/) - Starts n8n as a local process on port
45678 - Initializes the SQLite database and runs all migrations
- Sets up ChromaDB for semantic search
- Bootstraps n8n (creates admin account, imports workflows)
- Auto-detects installed coding agent CLIs
- Opens the Setup Wizard in the UI
Setup Wizard
The 5-step onboarding wizard walks you through initial configuration:
- LLM Provider — Enter a cloud API key (Anthropic, OpenAI, Google, OpenRouter) or connect a self-hosted model server (Ollama, LM Studio, or any OpenAI-compatible endpoint)
- n8n Check — Detects Node.js, installs n8n locally if needed, and auto-configures it
- Coding Agent + Repo — Select an agent (Claude Code, Gemini CLI, or Codex) and add your first repository
- Team Setup — Add team members so Laya can recognize actors in events
- Rules — Configure basic event filtering (e.g., ignore bot messages)
How n8n Works with Laya
n8n is the integration gateway that connects Laya to your external services. It runs as a local Node.js process on port 45678 and handles all platform-specific communication.
There are two types of n8n workflows:
- Ingestion workflows — Listen to external services (Gmail, Slack, Jira, etc.) and forward normalized events to the Laya Engine at
POST http://127.0.0.1:8420/events - Executor workflows — Receive action payloads from Laya and execute them on the target platform (send an email, post a Slack message, create a Jira comment)
n8n Local Installation
n8n runs as a local Node.js process. The Tauri desktop app manages the n8n lifecycle automatically (starts on app launch, stops on quit).
| Setting | Value |
|---|---|
| Port | 45678 (avoids conflict with a user's own n8n on default 5678) |
| Installation path | ~/.laya/n8n_module/ (installed via npm) |
| n8n binary | ~/.laya/n8n_module/node_modules/.bin/n8n |
| Data directory | ~/.laya/n8n/ (N8N_USER_FOLDER) |
| Default admin email | laya@local.host |
| Default admin password | LayaAutoAdmin2026! |
If you're building from source, the setup script installs n8n for you:
# Automatic (via setup script)
./scripts/setup-dev.sh
# Manual installation
mkdir -p ~/.laya/n8n_module ~/.laya/n8n
npm install --prefix ~/.laya/n8n_module n8n
Lightweight footprint: n8n runs as a simple Node.js process — no containers, no VMs. It starts fast, uses minimal memory, and is easy to debug.
Auto-Provisioning
On startup, the Tauri app starts n8n as a local process, then the Engine provisions it automatically:
- Tauri detects Node.js and starts
~/.laya/n8n_module/node_modules/.bin/n8non port 45678 - Engine waits for n8n to become healthy (up to 30 seconds)
- Creates the admin account (or logs in if it already exists)
- Generates an API key with full workflow and credential scopes
- Imports all bundled ingestion & executor workflows from
n8n/workflows/ - Stores the API key and admin password in the OS keychain
This process is fully idempotent — it's safe to restart and won't create duplicates. n8n is automatically stopped when you quit the Laya app.
Manual Setup
If auto-provisioning doesn't work (e.g., custom n8n instance or external server), you can configure manually:
- Open the n8n dashboard at
http://localhost:45678 - Create an account and generate an API key under Settings → API
- In Laya, go to Settings → Integrations and enter the API key manually
- Import workflows from the
n8n/workflows/directory via n8n's import UI
Environment Variables
| Variable | Default | Description |
|---|---|---|
N8N_URL | http://localhost:45678 | Override n8n base URL |
LAYA_N8N_OWNER_EMAIL | laya@local.host | Admin account email |
LAYA_N8N_OWNER_PASSWORD | LayaAutoAdmin2026! | Admin account password |
Connecting Platforms
All integrations are set up directly through the Laya UI — you never need to log into n8n. When you connect a platform, Laya automatically creates the n8n credentials, clones the appropriate ingestion and executor workflows, and activates them.
General Steps
- Go to Settings → Integrations
- Click the platform you want to connect
- Enter your credentials (API key or OAuth) in the modal
- Laya validates the credentials, provisions n8n workflows, and activates them automatically
- A green indicator confirms the connection is active
Multi-Account Support
You can connect multiple accounts for the same platform (e.g., "Work Gmail" and "Personal Gmail"). Each connection gets its own credentials, workflows, and event stream. Give each a unique name when connecting.
Gmail
| Property | Value |
|---|---|
| Auth | OAuth2 (opens Google sign-in in your browser) |
| Trigger | Polling (every minute, INBOX only) |
| Actions | Send, reply, forward emails |
Requires a Google OAuth client (client ID + secret). If you haven't set one up, Laya will prompt you to enter your OAuth app credentials first, then open the Google consent screen in your browser.
Slack
| Property | Value |
|---|---|
| Auth | Bot Token (API key) |
| Trigger | Webhook (real-time via Slack Events API) |
| Actions | Send messages, post thread replies |
Enter your Slack Bot Token in the connect modal. Events arrive in real-time with channel, thread, and mention metadata.
Jira
| Property | Value |
|---|---|
| Auth | API Token (email + token) |
| Trigger | Polling (every minute) |
| Actions | Add comments, update ticket fields |
Enter your Jira email and API token. The workflow polls for recently updated issues and includes project, labels, priority, and status metadata.
GitHub
| Property | Value |
|---|---|
| Auth | Personal Access Token |
| Trigger | Webhook (real-time) |
| Actions | Create PRs, add comments |
Enter your GitHub username and PAT. Supports PRs, issues, pushes, reviews, and CI checks.
Bitbucket
| Property | Value |
|---|---|
| Auth | App Password |
| Trigger | Webhook (real-time) |
| Actions | Create PRs, add comments |
Handles PR events, build status changes, branch pushes, and code review requests.
Google Calendar
| Property | Value |
|---|---|
| Auth | OAuth2 (opens Google sign-in in your browser) |
| Trigger | Polling (scheduled) |
| Actions | Create and update events |
Uses the same Google OAuth client as Gmail. If you've already set up Gmail, the OAuth client credentials are reused automatically.
Outlook
| Property | Value |
|---|---|
| Auth | Microsoft OAuth2 |
| Trigger | Polling / Webhook (depending on Graph API config) |
| Actions | Send/reply emails, create/update calendar events |
Covers both Outlook email and calendar. Requires a Microsoft OAuth client (client ID + secret).
Linear
| Property | Value |
|---|---|
| Auth | API Key |
| Actions | Create issues, add comments |
Enter your Linear API key. Linear events are ingested and actions are executed via the GraphQL API.
Notion
| Property | Value |
|---|---|
| Auth | Internal Integration Token |
| Trigger | Polling (page updates in configured databases) |
| Actions | Create pages, update properties |
Create a Notion internal integration, share the relevant databases with it, and enter the integration token. Laya polls for page changes and can create or update pages via the Notion API.
Removing a Connection
To disconnect a platform, click the connection name in Settings → Integrations and select Remove. Laya will deactivate and delete the cloned workflows, remove the n8n credential, and clear the keychain entry.
Custom Workflows
Laya's built-in integrations cover the most common platforms, but you can create your own n8n workflows to ingest events from any source. The only requirement is that your workflow normalizes its output into the Laya Event format and POSTs it to the Engine.
How It Works
- Open the n8n dashboard at
http://localhost:45678(credentials are shown in the n8n section above) - Create a new workflow with a trigger of your choice (webhook, polling, cron, etc.)
- Add your platform-specific nodes to fetch or receive data
- Add a Set node to transform the data into the Laya Event format (see schema below)
- Add an HTTP Request node as the final step to POST the normalized event to
http://127.0.0.1:8420/events - Activate the workflow
The Laya Event Format
Every event POSTed to Laya must conform to this JSON schema. The endpoint is POST http://127.0.0.1:8420/events with Content-Type: application/json.
{
"event_id": "evt_myplatform_unique_id_here",
"timestamp": "2026-04-05T14:30:00Z",
"source": {
"platform": "myplatform",
"connection_id": "optional_workflow_or_account_id",
"raw_event_type": "task_created"
},
"actor": {
"name": "Jane Smith",
"email": "jane@company.com",
"platform_handle": "jsmith"
},
"subject": {
"type": "ticket",
"id": "TASK-42",
"title": "Investigate payment timeout errors",
"url": "https://myplatform.com/tasks/42"
},
"content": {
"body": "Payment gateway timing out for EU customers since 3pm.",
"attachments": [],
"metadata": {
"custom_priority": "high",
"project": "payments"
}
}
}
Field Reference
| Field | Required | Description |
|---|---|---|
event_id | Yes | Globally unique ID. Use a deterministic format (e.g., evt_{platform}_{item_id}_{timestamp}) so retries are deduplicated. |
timestamp | Yes | ISO 8601 UTC timestamp of when the event occurred in the source system. |
source.platform | Yes | Short name for your platform (e.g., "notion", "trello", "pagerduty"). Use lowercase, no spaces. |
source.connection_id | No | Identifier for the specific account or workflow. Used by Laya to resolve which Space the event belongs to. |
source.raw_event_type | Yes | Platform-specific event type (e.g., "task_created", "alert_fired"). Preserved for classification and debugging. |
actor.name | Yes | Display name of the person or system that triggered the event. |
actor.email | Yes | Email address. Laya uses this to match against your Team Directory and determine the actor's relationship (teammate, manager, external, etc.). Use "" if unavailable. |
actor.platform_handle | No | Platform-specific username. Used as a fallback for team matching. |
subject.type | Yes | One of: ticket, pull_request, build, thread, email_thread, meeting. Choose the closest match. |
subject.id | Yes | Platform-specific identifier (e.g., "TASK-42", "#312"). |
subject.title | Yes | Human-readable title or subject line. |
subject.url | No | Direct link to the item in the source platform. |
content.body | Yes | Main text content (description, message body, comment text). Use "" if unavailable. |
content.attachments | No | Array of attachment URLs or filenames. Defaults to []. |
content.metadata | No | Object for any platform-specific fields (labels, priority, assignee, etc.). Defaults to {}. These are stored and available to the AI pipeline for enrichment. |
Choosing subject.type
Pick the type that best describes the item:
| Type | Use for |
|---|---|
ticket | Jira issues, Linear issues, Trello cards, support tickets, tasks |
pull_request | GitHub/Bitbucket PRs, merge requests, code reviews |
build | CI/CD results, deployment notifications, build failures |
thread | Slack messages, Discord messages, chat threads |
email_thread | Emails, newsletters, support inbox messages |
meeting | Calendar events, standups, scheduled calls |
The Final n8n Node
Your workflow's last node should be an HTTP Request node configured as:
| Setting | Value |
|---|---|
| Method | POST |
| URL | http://127.0.0.1:8420/events |
| Body Content Type | JSON |
| Body | The normalized event object (use expressions to map fields from previous nodes) |
Testing Your Workflow
You can test the event format directly from your terminal before wiring up the full workflow:
curl -X POST http://localhost:8420/events \
-H "Content-Type: application/json" \
-d '{
"event_id": "evt_test_001",
"timestamp": "2026-04-05T14:30:00Z",
"source": {
"platform": "test",
"raw_event_type": "test_event"
},
"actor": {
"name": "Test User",
"email": "test@example.com"
},
"subject": {
"type": "ticket",
"id": "TEST-1",
"title": "Test Event"
},
"content": {
"body": "Testing custom workflow integration."
}
}'
A successful response returns HTTP 202 with:
{ "event_id": "evt_test_001", "status": "queued" }
The event will appear in your feed within seconds as the AI pipeline processes it into an Action Card.
Tip: Use deterministic event_id values based on the source data (e.g., platform + item ID + timestamp) rather than random UUIDs. This ensures that if n8n retries a delivery, Laya deduplicates it instead of creating a duplicate card.
Tip: The content.metadata field is your escape hatch for platform-specific data. Anything you put here is stored and visible to the AI pipeline — the router and stager models can use it for better classification and action suggestions. For example, including a "severity": "critical" field will help Laya prioritize the event correctly.
Views & Layouts
The Pulse is the main feed for interacting with your Action Cards. It supports two view modes accessible from the header:
- Card View — 3-column grid of grouped cards, best for visual scanning. Context-grouped cards are clustered together automatically when smart grouping is enabled.
- List View — Dense tabular layout, best for rapid triage of many items
Click any card to open its Detail Panel on the right, showing the full intelligence report, staged output (draft replies, code diffs), and action buttons.
Filters & Sort
The header toolbar provides comprehensive filtering:
| Control | Options | Default |
|---|---|---|
| Date Navigation | Previous/Next day, Today button | Today |
| Space Filter | All Spaces, or specific space | All Spaces |
| Sort | Newest, Priority, Persona, Category, Source | Newest |
| Status Filter | Processing, Ready, Needs Approval, Running, Failed, Done, Dismissed | All |
| Priority Filter | Critical, High, Medium, Low | All |
| Archived | Show/hide archived cards | Hidden |
| Search | Text search with optional "Search all days" mode | Empty |
Filters are persisted to the backend so they survive page reloads and app restarts. The Search all days mode searches across all dates, not just the currently selected day.
Bulk Actions
Select multiple cards and apply actions in bulk via the bulk actions dropdown:
- Mark Done — Mark all selected cards as done
- Dismiss — Dismiss all selected cards
- Reopen — Reopen dismissed/done/failed cards
- Archive / Unarchive — Bulk archive or unarchive
- Delete — Permanently remove selected archived cards
Card Actions
Each card provides quick actions depending on its status:
| Action | Description |
|---|---|
| Mark as Done | Confirm the card is handled. Moves to done status. |
| Dismiss | Reject or skip the card. Optionally provide a reason (used for AI learning). |
| Archive | Hide from feed. Can be reopened later. Preserves original status. |
| Reopen | Bring back a dismissed, archived, or failed card for reprocessing. |
| Approve Agent | Start a coding agent to work on the task (for requires_approval cards). |
| Execute Action | Run a suggested action (send email, post comment) via n8n. |
| Run Agent | Run a coding agent (Claude Code, Gemini CLI, Codex) on the card or its entity group. Provide a custom prompt and interact via the workspace. |
| Delete | Permanently remove an archived card and all its data. |
Card Statuses
Cards flow through a lifecycle of statuses:
| Status | Meaning | Visual |
|---|---|---|
pending | Event received, being processed by AI pipeline | Amber pulse glow |
ready | Card fully processed, ready for user action | Warm peach tint |
requires_approval | Coding agent needs user approval before starting | Violet pulse glow |
agent_running | Coding agent actively working in a workspace | Lavender tint |
awaiting_input | Agent paused, waiting for user decision | Amber tint |
done | Completed and confirmed by user | Soft emerald |
failed | Processing or execution error (can be reopened) | Soft red |
dismissed | Rejected by user (can be reopened) | Muted gray |
archived | Hidden from feed (can be reopened or deleted) | Dashed border |
Bookmarks
Bookmark any card for quick access later. Bookmarked cards appear across all dates and statuses when the bookmark filter is active.
- Click the bookmark icon on any card (list view, card view, or card detail)
- Toggle the bookmark filter in the feed header to show only bookmarked cards
- Bookmarks persist across sessions and ignore date navigation
- Unbookmark by clicking the icon again
Run Agent
Any card or entity group can have a coding agent run against it. Press Ctrl+A (Cmd+A on Mac) or click Run Agent on a card to open the agent dialog:
- Custom prompt — Describe what you want the agent to do (investigate, code, research, etc.)
- Agent selection — Choose Claude Code, Gemini CLI, or Codex (defaults to your configured agent)
- Working directory — Defaults to
~/.laya/tmp/research/<card_id>/for research sessions, or your repo directory for code tasks - Additional directories — Pass extra repo paths for the agent to access
During execution, the agent streams progress to the workspace timeline. You can:
- Answer questions — The agent may ask for approval or clarification; respond directly in the workspace
- Dismiss questions — Skip pending prompts without answering
- Resume sessions — Continue a completed or paused session with a new freeform prompt
- Browse files — View output files created during research sessions
Agent sessions can also run at the entity group level, where a single session covers all cards in a group. The agent receives a CONTEXT.md file with the group summary and card details.
Daily Briefing
Laya generates a synthesized daily briefing at your configured time (default 7:00 AM). The briefing aggregates overnight activity into three sections:
- Events & Meetings — Calendar events and notable communications
- Action Items — Tasks requiring your attention, ranked by priority
- Key Updates — Important changes filtered from noise
Configure the briefing schedule under Settings → Briefing.
Coherence — Entity Search
Coherence is Laya's cross-platform entity search and lifecycle tracking feature. Access it from the Coherence tab in the main navigation.
Search for any entity — a person, ticket ID, PR number, project name — and Coherence traces its complete history across all connected platforms.
How It Works
Coherence uses a three-phase search algorithm:
- Discovery — Runs semantic search (ChromaDB), fuzzy/SQLite search, and entity table lookup in parallel, then merges results via Reciprocal Rank Fusion (RRF)
- Expansion — Fetches all cards for matched entities plus cross-references
- Clustering — Groups results by connected entities, orders chronologically, and auto-detects narrative chapters
Features
- Supports identifier patterns like
PR-540,BUG-123, or natural language queries - AI-generated narratives explain each cluster's story with chapter detection
- Real-time narrative streaming via WebSocket
- Remove irrelevant clusters from results, or restore them later
- Export traces as markdown
- Save and rerun traces as new data arrives
Traces & Narratives
Each search creates a trace that is saved for later reference. Traces contain:
- Clusters — Groups of related entities with timelines
- Chapters — Auto-detected lifecycle phases (Created, Discussion, Code Review, Resolved, etc.)
- Narrative — AI-generated summary of the entity's story
- Search metadata — Diagnostics about which search methods contributed results
Traces can be rerun to pick up new events, and exported as markdown reports.
Context Association — Semantic Grouping
Context association automatically links related cards across different platforms and entity types. When a new card is emitted, Laya searches for semantically similar existing cards and groups them together if they belong to the same real-world context.
How It Works
- Semantic search — New cards are compared against existing cards in ChromaDB using vector similarity
- Confidence thresholds — Matches below 0.20 distance are auto-confirmed; matches between 0.20–0.30 are confirmed via LLM call
- Context groups — Linked cards share a
context_idand display a context label in the feed - User overrides — Manual merge (Link Dialog) and unlink operations are respected; user-split groups are never re-merged
Smart Grouping in Feed
When smart grouping is enabled (Settings → Briefing → Smart Grouping), context-associated cards are clustered together in the feed. Cards show a "linked" badge when they belong to a context group.
Context Association — Learning Pipeline
Laya learns from your link and unlink corrections to improve future grouping accuracy. The learning pipeline runs every 6 hours and:
- Collects unprocessed link/unlink corrections (up to 40 per batch)
- Sends them to the LLM to extract generalizable rules (e.g., "bills and payment receipts for the same service should be grouped")
- Stores extracted rules in the
context_rulestable - Injects these rules into future context confirmation prompts
Rules are per-space and improve automatically as more corrections are processed. View active rules and correction history in Settings → Audit Log.
Egress — Outbound Actions
The egress system handles all outbound communication with external platforms. Instead of switching to Slack or Gmail to take action, do it directly from Laya.
Supported Actions
| Platform | Actions |
|---|---|
| Gmail / Outlook | Send, reply, forward emails |
| Slack | Post messages, reply in threads |
| Jira | Add comments, update tickets |
| GitHub / Bitbucket | Create PRs, add comments |
| Calendar | Create and update events |
| Linear | Create issues, add comments |
| Notion | Create pages, update properties |
How to Use
- From a card — Click "Execute" on a suggested action. Laya shows a preview before sending.
- Compose modal — Press
Ctrl+C(Cmd+C on Mac) to open the compose modal and send a new message to any connected platform. - Card-triggered — Approve suggested actions directly from Action Cards.
Connections
Platform connections are managed under Settings → Integrations. Each connection tracks its status, credentials (stored in your OS keychain), and available capabilities. Use the Test Connection button to verify connectivity before sending.
Omni — Rolling Summary
Omni is Laya's cross-platform summary engine. It synthesizes all professional activity across every connected platform into a single, unified "big picture" view. Access it from the Omni tab in the main navigation.
Unlike the feed (which shows individual cards) or briefings (which cover a single morning), Omni maintains a rolling summary that progressively compresses older information while keeping recent details sharp.
Temporal Layers
Every Omni snapshot is organized into four temporal layers:
| Layer | Scope | Content |
|---|---|---|
| Attention | Needs action now | Aging PRs, unanswered emails, stale blockers |
| Recent | Last 24–48 hours | Specific details — named PRs, email threads, decisions |
| Period | This week / sprint | Aggregates and trends, compressed from recent items |
| Milestone | Older inflection points | Releases, team changes, architecture shifts that still matter |
Each refresh re-synthesizes older layers, folding detail into aggregates: Recent → Period → Milestone → Gone. This ensures the summary stays dense and useful without unbounded growth.
Hybrid Generation
Omni uses two generation strategies to balance cost and freshness:
- Incremental updates — When new cards arrive, they are appended to the Recent layer as structured items. No LLM call needed; updates are debounced in 10-second batches.
- Full resynthesis — The LLM compresses all layers, folds older items, and produces a clean versioned snapshot. Three triggers can fire resynthesis:
- Scheduled (EOD) — Runs once daily at a configurable time (default 5:00 PM in your timezone).
- Rolling interval — Triggers every N hours (default 4). Set to 0 to disable.
- Event threshold — Triggers after N new events since the last resynthesis (default 50). Set to 0 to disable.
Density Modes
Control how much detail each Omni snapshot contains under Settings:
| Mode | Items per Section | Words per Item | Best for |
|---|---|---|---|
| Compact (default) | 3 | ~25 | One-screen glance |
| Standard | 5 | ~40 | Balanced detail |
| Detailed | 8 | ~50 | Comprehensive overview |
Pins & Time Travel
Pins let you mark items that must survive compression. Pinned items appear in every resynthesized snapshot exactly as written, placed in the appropriate temporal layer.
Time travel — use the version slider in the Omni header to browse previous snapshots. Each resynthesis creates a new versioned snapshot, so you can see how your summary evolved over time.
Drill-Down
Click on any item's source card links to open the Insight view — a side-by-side panel showing full card details alongside a contextual chat interface where you can ask questions about those specific cards.
Space Awareness
Each space maintains its own independent Omni summary. Switch between spaces using the tabs at the top of the Omni page.
Omni Settings
Configure under Settings:
| Setting | Default | Description |
|---|---|---|
| Resynthesis Time | 17:00 | Daily scheduled resynthesis time (HH:MM, local timezone) |
| Density | compact | Summary detail level: compact, standard, or detailed |
| Rolling Interval | 4 hours | Trigger resynthesis every N hours (0 to disable) |
| Event Threshold | 50 | Trigger resynthesis after N new events (0 to disable) |
AI Models
Laya uses multiple AI models for different pipeline stages. Configure under Settings → Models.
Pipeline Roles
| Role | Purpose | Recommendation |
|---|---|---|
| Router | Fast classification (priority, category, persona) | Use a fast, cheap model |
| Stager | Synthesize action cards, intelligence reports, and Omni summaries | Use a capable model |
| Chat | Conversational responses in chat interface | Use a conversational model |
| Coherence | Cross-platform entity search and narrative generation | Use a capable model |
Supported Cloud Providers
| Provider | Model Format | Example |
|---|---|---|
| Anthropic | anthropic/model-name | anthropic/claude-sonnet-4-6 |
| OpenAI | openai/model-name | openai/gpt-4o |
gemini/model-name | gemini/gemini-2.0-flash-exp | |
| OpenRouter | openrouter/provider/model | openrouter/openai/gpt-4-turbo |
Advanced Pipeline Settings
| Setting | Default | Description |
|---|---|---|
| Model Timeout | 480s | Maximum wait time for LLM API responses |
| LLM Retries | 3 | Retry attempts for failed LLM calls (exponential backoff) |
| Event Queue Retries | 3 | Max retries for failed event processing |
| Concurrency | 4 | Number of events to process simultaneously |
| Summary Debounce | 30s | Quiet period before incorporating new cards into the daily summary |
| Group Summary Debounce | 15s | Quiet period per entity before updating the group summary |
| Event Batch Window | 3s | Collection window before batch-routing multiple events. Set to 0 to disable. |
| Event Batch Max Size | 10 | Maximum events classified in one router call |
Self-Hosted Models
Laya supports self-hosted model providers. Add them under Settings → Models → Local Providers.
Supported Provider Types
| Type | Software | Default URL | Auto-Discovery |
|---|---|---|---|
lmstudio | LM Studio | http://localhost:1234 | Rich metadata with capabilities |
ollama | Ollama | http://localhost:11434 | Basic model list |
openai_compatible | vLLM, LMStack, etc. | Custom | Standard OpenAI format |
After adding a provider, its models appear in the model selection dropdowns. Use them like: my-provider-id/model-name.
Tip: Use the Test Connection button to verify provider connectivity and check model capabilities (tool calling, structured output, vision).
Coding Agents
Laya can spawn real coding agent CLIs to work on tasks in your repositories. Configure under Settings → Agent.
Supported Agents
| Agent | Binary | Provider |
|---|---|---|
| Claude Code | claude | Anthropic |
| Gemini CLI | gemini | |
| Codex CLI | codex | OpenAI |
Execution Modes
- Requires Approval (recommended) — Card status becomes
requires_approval; you must click "Approve" before the agent starts - Automatic — Agent runs immediately when an ENGINEER card is ready (use with caution)
Agent paths are auto-detected on startup. If detection fails, specify the binary path manually in settings.
Spaces & Sources
Spaces let you organize your workflow into separate contexts (e.g., Work, Personal, Side Projects). Configure under Settings → Spaces.
What Spaces Control
- Event routing — Events from assigned sources land in the correct space
- Feed filtering — Filter the feed by space in the header toolbar
- Model overrides — Each space can use different AI models
- API key overrides — Each space can have its own provider API keys
- Repository assignment — Link repos to spaces for coding agent context
- Pause/resume — Temporarily stop all ingestion for a space
Default Space: A "Default" space always exists and cannot be deleted. Unknown or unassigned sources automatically land here.
Source Management
Sources are n8n workflows linked to spaces. When an ingestion workflow sends an event, Laya resolves the space via the workflow ID (source.connection_id). You can reassign sources between spaces at any time under the Spaces settings.
Rules & Filters
Rules let you automatically filter incoming events before they hit the AI pipeline. Configure under Settings → Rules.
Rule Structure
Each rule has a condition and an action:
- Drop — Discard the event silently
- Allow — Bypass remaining rules and allow the event through
Rules are evaluated in order. The first matching rule determines the outcome. If no rule matches, the event passes through.
Available Fields
actor.email actor.name actor.platform_handle
source.platform source.connection_id source.raw_event_type
subject.type subject.id subject.title
content.body content.metadata.*
Operators
| Operator | Behavior |
|---|---|
equals | Case-insensitive exact match |
not_equals | Negation of equals |
contains | Substring match (case-insensitive) |
starts_with | Prefix match |
ends_with | Suffix match |
in | List membership |
Examples
// Ignore all bot messages
{ "field": "actor.email", "operator": "contains", "value": "bot" } → drop
// Ignore a specific Slack channel
{ "field": "content.metadata.slack_channel", "operator": "equals", "value": "#random" } → drop
// Always allow critical priority
{ "field": "priority", "operator": "equals", "value": "CRITICAL" } → allow
Classification Feedback & Learned Rules
Laya learns from your corrections. When you change a card's priority or persona, the correction is logged. After enough corrections accumulate (15+), Laya's learning pipeline extracts generalizable rules from the patterns.
- Manual rules — Created by you in Settings → Rules
- Learned rules — Automatically extracted by the AI from your correction patterns
Both manual and learned rules are injected into the router prompt to improve future classifications. Over time, Laya requires fewer corrections as it learns your preferences.
Team Directory
The team directory helps Laya recognize actors in events and understand organizational relationships. Configure under Settings → Team.
| Field | Description |
|---|---|
| Name | Display name |
| Email address (used to match event actors) | |
| Role | Job title or function |
| Relationship | manager, teammate, direct_report, peer, or external |
When an event arrives, the Engine matches actor.email against the team directory to enrich context with role and relationship information.
Repositories
Add your code repositories so coding agents can operate in the right context. Configure under Settings → Repos.
- Use the Browse button to select a local directory
- Laya auto-detects the platform (GitHub, Bitbucket) and remote ID
- Assign repos to Spaces so the right agent gets the right context
Features & Scheduling
Configure feature toggles and scheduling under Settings → Features.
Daily Briefing
| Setting | Default | Description |
|---|---|---|
| Enabled | On | Toggle briefing generation |
| Time | 07:00 | Time of day (24-hour format) |
| Timezone | America/New_York | IANA timezone (46 timezones available) |
Context Association
| Setting | Default | Description |
|---|---|---|
| Enabled | On | Toggle automatic semantic grouping of related cards |
Group Summaries
| Setting | Default | Description |
|---|---|---|
| Enabled | On | Toggle rolling LLM summaries for multi-card entity groups |
Appearance
Customize Laya's visual style under Settings → Appearance.
| Setting | Default | Description |
|---|---|---|
| Theme | Dark | Switch between Dark (warm-tinted dark grays) and Light (warm cream background with inverted surface scale) |
| Glass effect | Off | Frosted glassmorphism overlay with backdrop blur on cards, tooltips, and menus |
| Card colors | On | Enable color-coded card borders based on priority or persona |
| Accessible colors | Off | Shift color hues for improved contrast and color-blind accessibility |
| Card descriptions | On | Show card description text in feed views |
| Card size | Default | Toggle between compact and relaxed card layout |
| Font scale | 14 (Default) | Adjust font size: Compact (12), Default (14), Relaxed (15), Large (16) |
| Reduced motion | Off | Disable animations for motion-sensitive users |
All preferences are stored in localStorage and applied instantly.
Budget & Costs
Track and control LLM spending under Settings → Budget or the Dashboard.
| Feature | Description |
|---|---|
| Feature breakdown | Costs grouped by feature: Pulse, Coherence, Omni, Chat, Briefing, Egress, System |
| Step breakdown | Expandable per-feature cost details: Routing, Entity Resolution, Context Learning, Stager, Trace, etc. |
| Monthly history | Monthly cost aggregation with trend tracking |
| Monthly cap | Set a maximum monthly spend. When exceeded, Laya pauses AI processing and notifies you. |
| Pause/Resume | Manually pause or resume AI processing to control costs |
The Dashboard includes an interactive Feature Cost Chart that visualizes costs by feature with expandable step-level details.
Data & Retention
Configure how long Laya retains historical data under Settings → Data.
| Setting | Default | Applies to |
|---|---|---|
| Card Retention | 90 days | Cards in terminal states: archived, dismissed, done, failed |
| Chat Retention | 90 days | Idle chat conversations |
| Audit Retention | 90 days | Audit log entries |
| Omni Retention | 30 days | Omni snapshots (latest per space is always preserved) |
A housekeeping task runs daily at ~00:00 UTC to remove expired data. Active cards and recent conversations are never auto-deleted.
Privacy Tiers
Laya classifies event data into three privacy tiers:
| Tier | Sources | Processing |
|---|---|---|
| Tier 1 (Metadata) | All sources | Always cloud-processable |
| Tier 2 (Default) | Jira, Bitbucket, Slack channels, Calendar | Cloud OK with audit trail |
| Tier 3 (Sensitive) | Gmail, Outlook, Slack DMs | Warning or local-only |
Tier 3 Processing Modes
cloud_with_warning(default) — Allow cloud models but show a privacy indicator on the cardlocal_only— Force all Tier 3 data through local models only (e.g., Ollama)
API Key Storage
All API keys are stored in your operating system's keychain, never in config files or environment variables:
- macOS — Keychain Access (service:
laya-engine) - Windows — Credential Manager
- Linux — Secret Service / Pass
On engine startup, keys are loaded from the keychain into memory. They never touch disk in plaintext.
Local-Only Mode
For maximum privacy, you can run Laya entirely without cloud models:
- Install Ollama or LM Studio locally
- Add the local provider under Settings → Models → Local Providers
- Set all model roles (Router, Stager, Chat) to local models
- Set
tier3_processingtolocal_only
In this mode, no data ever leaves your machine — complete air-gapped privacy.
Processing Pipeline
Every event flows through Laya's multi-stage AI pipeline:
- INGEST — Parse event, resolve actor from team directory, store raw event, resolve space
- RULES — Evaluate user-defined filter rules; drop or pass
- ROUTER (Fast LLM) — Classify priority, category, persona; extract entities; build research plan; query memory for related events
- WORKERS (6 Specialized Personas) — Engineer (code analysis, agent spawning), Comms (draft replies), Ops (calendar synthesis), Finance (invoices, budgets), HR (people ops), Sales (pipeline tracking)
- STAGER (Strong LLM) — Synthesize research + drafts into polished card; generate intelligence report; prepare suggested actions
- EMIT — Store card in database, embed summary in ChromaDB, attempt context association with related cards, trigger group summary, push to UI via WebSocket
- GROUP SUMMARY — Generate or update rolling LLM summaries for multi-card entity groups (fire-and-forget background task)
- TRACE — Index entities into ChromaDB for Coherence search
- LEARN — Extract classification rules from user feedback (priority/persona corrections)
- CONTEXT LEARN — Extract context grouping rules from user link/unlink corrections (runs periodically)
- OMNI — Append card to rolling cross-platform summary (debounced incremental update)
Every step is recorded in the Audit Log (Settings → Audit) with model used, token counts, latency, and success/failure status. Failed events retry with exponential backoff (up to 3 attempts); permanently failed events are visible in Settings → Audit Log and can be manually retried.
Event Schema
Events sent from n8n to the Laya Engine follow this schema:
{
"event_id": "evt_unique-id",
"timestamp": "2026-03-19T14:30:00Z",
"source": {
"platform": "gmail|slack|jira|github|bitbucket|calendar|outlook|linear|notion",
"connection_id": "n8n-workflow-id",
"raw_event_type": "platform_specific_type"
},
"actor": {
"name": "Alice Smith",
"email": "alice@company.com",
"platform_handle": "@alice"
},
"subject": {
"type": "ticket|pull_request|build|thread|email_thread|meeting",
"id": "PROJ-123",
"title": "Fix login timeout bug",
"url": "https://jira.company.com/browse/PROJ-123"
},
"content": {
"body": "Full event content text...",
"metadata": { "platform_specific": "fields" }
}
}
Configuration Files
All user configuration lives in ~/.laya/:
| File | Purpose |
|---|---|
settings.json | Main engine configuration (models, pipeline, privacy, briefing, n8n) |
team.json | Team member directory |
rules.json | Event filter rules |
repos.json | Repository definitions |
data/laya.db | SQLite database (events, cards, actions, audit log) |
data/chromadb/ | ChromaDB vector store for semantic search |
n8n_module/ | n8n npm installation (binary at node_modules/.bin/n8n) |
n8n/ | n8n data directory (database, encryption key, credentials) |
logs/ | Application log files |
Note: All config files are created automatically on first run with sensible defaults. You can edit them directly or use the Settings UI.
Custom Prompts
Laya's AI pipeline uses system prompts at every stage — routing, staging, summarization, chat, and more. All prompts are hardcoded with sensible defaults, but you can override any of them by placing a text or markdown file in the ~/.laya/prompts/ directory.
How it works: On startup (and via the reload API), Laya scans ~/.laya/prompts/ for recognized filenames. If a file is found, its content replaces the corresponding hardcoded system prompt. If the file is missing or deleted, the built-in default is used. Laya never creates or modifies files in this directory — your custom prompts are purely additive.
Getting Started
# Create the prompts directory
mkdir -p ~/.laya/prompts
# Override the router prompt
cat > ~/.laya/prompts/router.md << 'EOF'
You are the Router for Laya. Classify incoming events with these priorities:
- CRITICAL: anything from the CEO or involving production outages
- HIGH: customer-facing issues, PRs awaiting my review
- MEDIUM: team discussions, assigned tickets
- LOW: everything else
...
EOF
# Reload without restarting the engine
curl -X POST http://127.0.0.1:8420/prompts/reload
Available Prompt Files
| File | Pipeline Stage | Description |
|---|---|---|
router.md | Router | Event classification (category, persona, priority, entities, research plan) |
stager.md | Stager | Synthesize worker findings into polished Action Cards with staged actions |
omni.md | Omni | Rolling cross-platform summary synthesis |
group_summary_initial.md | Group Summary | First summary for a multi-card entity group |
group_summary_rolling.md | Group Summary | Rolling update when new cards arrive for an existing group |
briefing.md | Briefing | Daily morning briefing generation |
summarizer.md | Summarizer | Incremental daily running summary |
summarizer_status_change.md | Summarizer | Updates the daily summary when a card's status changes |
engineer.md | Worker | ENGINEER persona — coding agent task preparation |
comms.md | Worker | COMMS persona — communication reply drafting |
sales.md | Worker | SALES persona — customer/prospect reply drafting |
hr.md | Worker | HR persona — people/hiring communication |
ops.md | Worker | OPS persona — calendar prep and operational briefings |
finance.md | Worker | FINANCE persona — financial event synthesis |
chat.md | Chat | Conversational chat system prompt |
chat_title.md | Chat | Conversation title generation |
chat_polish.md | Chat | Message polish/refinement |
learner.md | Learning | Extracts classification rules from user corrections |
context_learner.md | Learning | Extracts grouping rules from link/unlink actions |
trace_narrative.md | Coherence | Generates narrative summaries for entity traces |
trace_summary.md | Coherence | Generates concise summaries for trace clusters |
trace_filter.md | Coherence | Relevance filtering for trace search results |
Important Notes
- Full replacement: A custom prompt completely replaces the built-in default for that stage. You won't automatically receive improvements to default prompts after engine updates.
- JSON output prompts: Several prompts (router, stager, group_summary, omni, summarizer) instruct the LLM to return structured JSON. If your custom prompt omits these format instructions, the pipeline may fail to parse responses. Check the engine logs if cards stop appearing.
- Template variable: The
group_summary_initial.mdandgroup_summary_rolling.mdprompts support{timestamp}— it will be replaced with the current UTC date/time at call time. All other prompts are plain text. - Unrecognized files: Files that don't match a known filename are ignored. Check the engine logs for warnings about unrecognized files (e.g., a typo in the filename).
API Endpoints
| Endpoint | Description |
|---|---|
GET /prompts | Returns all 22 prompt keys with their override status |
POST /prompts/reload | Re-scans ~/.laya/prompts/ and hot-swaps overrides without restarting |
MCP Server
Laya exposes its toolset over the Model Context Protocol. Any MCP-compatible client — Claude Desktop, Cursor, VS Code, Zed, custom agents — can call into Laya to search your cards, fetch events, trace entities, run semantic search, and trigger outbound actions across all 9 connected platforms.
Transport: the MCP server is mounted on the running engine at http://127.0.0.1:8420/mcp/sse using Server-Sent Events. There is no subprocess to spawn — whenever Laya is running, the endpoint is live. The bundled Tauri app exposes it natively; no source install required. The in-app Claude Code coding agents use the same endpoint, so there is exactly one MCP path in the system.
Configuration
Open Settings → MCP in the desktop app. You'll find three controls:
- Tool scopes — toggles for Read, Write, and Egress. Only enabled categories are exposed to MCP clients. Changes take effect on the next call (no restart).
- Authentication — pick Bearer token (recommended) or Loopback only, no auth.
- Token — when bearer auth is enabled, the current token is shown (with reveal / copy / rotate controls). Rotating immediately invalidates the previous token.
Available Tools
| Scope | Tools |
|---|---|
| Read | search_cards, get_card, search_events, get_event, search_entities, get_entity, get_card_stats, get_recent_activity, get_cards_for_event, get_cards_by_entity, semantic_search, get_settings |
| Write | dismiss_card, archive_card, mark_card_done, reopen_card, update_theme, update_retention, update_briefing, update_notifications, update_feed_preferences |
| Egress | Per-platform actions for GitHub, Bitbucket, Jira, Linear, Gmail, Slack, Calendar, Outlook, and Notion (send messages, post comments, create issues, schedule events, …) |
Claude Desktop
Edit your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows) and add Laya as an SSE server:
{
"mcpServers": {
"laya": {
"type": "sse",
"url": "http://127.0.0.1:8420/mcp/sse",
"headers": {
"Authorization": "Bearer lyat_…"
}
}
}
}
Copy the bearer value from Settings → MCP. Restart Claude Desktop — Laya's tools appear in the picker as mcp__laya__*. If you've set auth mode to none, omit the headers block entirely.
Cursor & VS Code
Both Cursor and the VS Code MCP extension accept the same SSE config shape. Add a server entry under mcpServers (Cursor: ~/.cursor/mcp.json; VS Code: workspace .vscode/mcp.json or the MCP extension's settings UI) with "type": "sse", the SSE URL, and (when bearer auth is on) the Authorization header.
Scoping to a Space
Append ?space_id=<your-space> to the SSE URL to restrict all tool calls in that connection to a single Laya space:
{
"mcpServers": {
"laya-work": {
"type": "sse",
"url": "http://127.0.0.1:8420/mcp/sse?space_id=work",
"headers": { "Authorization": "Bearer lyat_…" }
}
}
}
Register the same MCP server multiple times under different names with different space_id values to give a client scoped views of each space.
Tuning Parameters
Laya exposes internal parameters that control the behavior, sensitivity, and resource usage of its AI pipeline. These have sensible defaults and do not need to be changed for normal operation. Advanced users can override them via the tuning section in ~/.laya/settings.json.
How to override: Add a tuning object to your ~/.laya/settings.json. Only include the parameters you want to change — omitted parameters use their defaults. Changes take effect on the next pipeline run (no restart required).
{
"tuning": {
"context_association_time_window_days": 14,
"trace_semantic_max_distance": 0.50
}
}
Context Association
Controls how Laya detects semantic relationships between cards from different sources.
| Parameter | Default | Description |
|---|---|---|
context_association_time_window_days | 7 | Only consider cards within this many days for grouping. Lower = fewer but more relevant matches. Higher = broader but more false positives. |
The distance thresholds for context association live in the smart_grouping section (not tuning):
| Setting | Default | Description |
|---|---|---|
smart_grouping.auto_confirm_threshold | 0.12 | ChromaDB cosine distance below which cards are auto-grouped without LLM confirmation. Lower = stricter. |
smart_grouping.confidence_threshold | 0.22 | Max distance for LLM-confirmed grouping. Cards beyond this are never grouped. |
Entity Resolution
| Parameter | Default | Description |
|---|---|---|
semantic_entity_threshold | 0.35 | Cosine distance threshold for semantic entity linking. Controls when entities (tickets, people, repos) are considered related across cards. |
entity_search_results | 5 | Number of ChromaDB results fetched per entity during semantic resolution. |
Classification Learning
Controls how Laya learns classification rules from user corrections (priority/persona adjustments).
| Parameter | Default | Description |
|---|---|---|
classification_learn_threshold | 15 | Minimum unprocessed corrections per space before the learner triggers. |
classification_learn_batch | 50 | Max corrections sent to the LLM in a single learning call. |
classification_learn_interval_hours | 6 | How often the scheduler checks for unprocessed corrections. |
Context Learning
Controls how Laya learns from user link/unlink actions to improve context grouping.
| Parameter | Default | Description |
|---|---|---|
context_learn_threshold | 10 | Minimum unprocessed context corrections before the learner triggers. |
context_learn_batch | 40 | Max context corrections sent to the LLM per learning call. |
context_learn_interval_hours | 6 | Scheduler interval for context learning checks. |
context_rules_max_injection | 20 | Max learned rules injected into the LLM confirmation prompt. |
context_corrections_max_injection | 10 | Max recent user link/unlink actions injected as examples. |
Trace / RAG Search
| Parameter | Default | Description |
|---|---|---|
trace_search_results | 30 | Results per search strategy (identifier, semantic, entity, text, fuzzy). |
trace_max_seeds | 20 | Max seed results retained after merging all search strategies. |
trace_semantic_max_distance | 0.65 | Max cosine distance for semantic search in traces. Lower = fewer but more relevant. |
Chat Retrieval
| Parameter | Default | Description |
|---|---|---|
chat_semantic_max_distance | 0.60 | Max cosine distance for semantic search in chat context. |
chat_context_items | 12 | Max context items (cards, events, entities) included in the chat prompt. |
Router & Feedback
| Parameter | Default | Description |
|---|---|---|
router_related_context_results | 3 | Related past cards fetched to provide context during event classification. |
feedback_time_window_days | 30 | Time window for querying user feedback patterns (approval/dismissal rates). |
corrections_retention_days | 30 | Days to keep processed corrections before automatic deletion. |
Pipeline Debounce & Batching
Control how Laya batches LLM calls to reduce costs during burst activity. Located under pipeline.debounce in settings.json.
| Parameter | Default | Description |
|---|---|---|
pipeline.debounce.daily_summary_seconds | 30 | Quiet period before processing accumulated cards into the daily summary. Higher = fewer LLM calls during bursts. |
pipeline.debounce.group_summary_seconds | 15 | Per-entity quiet period before updating the group summary. Cards arriving within this window are batched into one LLM call. |
pipeline.debounce.event_batch_window_seconds | 3 | Collection window for batch-routing. Set to 0 to disable (events process immediately). |
pipeline.debounce.event_batch_max_size | 10 | Max events per batch-router call. Larger = more savings but higher per-call latency. |
Cosine Distance Reference
Laya uses cosine distance in ChromaDB (range 0.0–1.0). The embedding model is nomic-ai/nomic-embed-text-v1.5 (768 dimensions).
| Distance | Meaning | Typical Use |
|---|---|---|
| 0.00–0.10 | Near-identical content | Same event, different wording |
| 0.10–0.20 | Very similar | Same topic, closely related |
| 0.20–0.35 | Moderately similar | Related topics, same domain |
| 0.35–0.50 | Loosely related | Same category, different subjects |
| 0.50+ | Unrelated | Different domains |
Keyboard Shortcuts
Laya supports keyboard shortcuts for common actions. Customize them under Settings → Keys.
| Shortcut | Action |
|---|---|
Ctrl+A / Cmd+A | Open Run Agent dialog |
Ctrl+C / Cmd+C | Open Compose modal |
Ctrl+B | Toggle bookmarks filter |
Ctrl+L | Toggle chat panel |
Ctrl+O | Go to Omni |
Ctrl+P | Go to Pulse (feed) |
Ctrl+F | Focus search box |
Ctrl+D | Toggle card descriptions |
Ctrl+Shift+D | Toggle compact/relaxed layout |
Ctrl+Enter | Send compose form |
R | Toggle recent items |
S | Toggle day summary |
Ctrl+[ / Ctrl+] | Navigate back / forward |
Troubleshooting
n8n won't connect
- Check Node.js is installed:
node --version(requires 18+) - Check n8n is installed:
ls ~/.laya/n8n_module/node_modules/.bin/n8n - Check n8n health:
curl http://localhost:45678/healthz - Manually start n8n:
N8N_PORT=45678 N8N_USER_FOLDER=~/.laya/n8n ~/.laya/n8n_module/node_modules/.bin/n8n start - Try manual bootstrap: Settings → Integrations → Auto-Configure
Events not appearing
- Verify the n8n workflow is active (green toggle in n8n dashboard)
- Check n8n workflow execution history for errors
- Verify credentials are configured in the n8n trigger node
- Check if a rule is dropping the event (Settings → Rules)
- Check engine logs at
~/.laya/logs/
LLM errors
- Verify your API key is valid (Settings → Models, check green dot)
- Check the Audit Log for specific error messages
- Try increasing the model timeout (Settings → Models → Advanced)
- If using local models, ensure the provider is running and accessible
Coding agent not detected
- Ensure the CLI binary is installed and in your PATH
- Try Auto-Detect in Settings → Agent
- Or set the binary path manually
Export diagnostics
For debugging, use the Export Diagnostics button at the bottom of the Settings page. This creates a ZIP file containing system info, sanitized config, recent logs, and database statistics.