Model or dataset
aayushch/laya avatar
aayushch/laya

Laya: a local-first notification command center that stages actions for approval

Laya is an open-source, local-first AI notification command center that aggregates Slack, Gmail, GitHub, Jira, Notion, Outlook, Calendar (and more) notifications using local LLMs via Ollama and LM Studio. Supports cloud models via BYOK.

753 stars120 forksPythonApache-2.0

At a glance

What is it?
Laya is a Python and Tauri application that intercepts events from Slack, Gmail, GitHub, Jira, Notion, Outlook and Calendar, has local or cloud models research and classify them, and presents ready-to-approve action cards instead of raw notifications. It is Apache-2.0 licensed and ships a local n8n gateway as the integration layer.
Who is it for?
Laya suits an individual or a small team drowning in notifications who wants a triage layer that runs on their own machine with Ollama or LM Studio, and who is willing to wire up API keys for the tools they want aggregated. It does not suit a regulated environment where notification content cannot leave the machine without review, and it does not suit anyone wanting a finished product, since it is a large surface with a v2 line still settling after the 2.2.1 release.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The pipeline is n8n, a Python engine and a Tauri front end

Laya calls itself an open-source, local-first AI notification command center, and the architecture diagram in the readme is the clearest statement of what it does:

text
Your Tools (Jira, Slack, Gmail, Bitbucket, Calendar)
         |
         v
      n8n (local Node.js) -- normalizes events
         |
         v
   Laya Engine (Python) -- classifies, researches, stages
         |
         v
    Laya UI (Tauri + Svelte) -- Action Cards you approve or dismiss
         |
         v
      n8n -- executes approved actions (creates PRs, sends replies, etc.)

The design point is that n8n appears twice, at both ends. It receives events from the outside world and normalizes them, and it is also the thing that executes approved actions at the end, creating pull requests or sending replies. The Python engine sits in the middle and does the intellectual work: classifying, researching and staging. The Tauri and Svelte interface is where a human approves or dismisses the result.

That last step is what makes the whole thing reviewable. The output is an action card with the work already done, so the answer exists before you open the original notification. A card you approve goes back to n8n and becomes a real action. A card you dismiss costs you one click.

The repository layout matches the diagram. There is an engine/ directory for the Python FastAPI backend, an n8n/ directory for the integration gateway, a ui/ directory for the front end, a landing/ directory for the site, a scripts/ directory, and docs/ for the documentation.

Local models by default, cloud models by choice

The model story is the local-first claim, and the readme spells out both halves of it.

Local inference goes through Ollama and LM Studio, and the same model choice applies to cloud providers: Claude models from Anthropic, GPT models from OpenAI, Gemini models from Google, and Llama models or any OpenAI-compatible endpoint through LiteLLM. The cloud routes use your own API keys, which is what the BYOK in the topic list refers to.

The more unusual piece is agent inference backends. Instead of calling an API, you can run the classification and synthesis pipeline on an installed CLI agent's own quota, by selecting a model of the form agent/<id>/<model>, with Claude Code, Codex, Gemini or Pi listed as the options. That means the pipeline inherits the subscription you already pay for rather than adding a separate metered API bill.

There is a difference in how strictly the JSON output is enforced, and the readme is honest about it. Claude Code enforces JSON schemas natively, while other agents use a best-effort schema plus retry. That is a real operational difference: on a non-Claude backend, expect retries and expect the occasional malformed response to be handled by a retry rather than a hard guarantee.

The privacy stance is described as three-tier data classification with cloud and local processing options, which means you can decide per stage or per space where the text goes. The Spaces feature, user-defined contexts grouping event sources with per-space model and API key configurations, is the mechanism for that, and it is also how you keep a work account's traffic separate from a personal one.

Learning from your corrections is the part worth understanding

Laya does more than filter. Several features are about inferring your preferences from the corrections you make, and this is the part that distinguishes it from a rules engine.

Context Association links related cards across platforms using semantic similarity and LLM confirmation, and it learns from your corrections to improve grouping accuracy over time. Cross-platform memory then does entity resolution, linking a ticket identifier in Jira to a pull request in Bitbucket to a phrase like the payment bug in a Slack message. That mapping is what lets a single view answer the question of whether a bug mentioned in chat is the one in your tracker.

Classification learning works the same way for priorities and personas. When you correct a card's priority or which persona it routed to, Laya extracts rules from those corrections and applies them to future notifications. Context learning does the same for linking and unlinking, producing natural-language context rules that are viewable and editable in Settings, with large rule sets consolidated automatically by an LLM.

The manual counterpart is the processing rules feature, which are automated and optionally AI-evaluated rules that act on incoming cards, tagging them, routing them, running an agent or sending an egress action. Every firing is recorded in a searchable firing log with its outcome, whether success, error or skipped, and the reason. That log matters: an automated action system without a record of what it did and why is one you cannot debug.

The audit and export feature closes the loop from the other side, letting you inspect dead events, ingestion errors and rule-filtered events in one place, retry or clear failures, and export filtered events or the audit log as JSON over any time window.

Hybrid search and a local document corpus

Retrieval is where the local-first approach gets concrete, and the design is a hybrid rather than pure vector search.

Chat and Coherence retrieval combine local vector search through ChromaDB with lexical BM25 ranking over SQLite FTS5, using the cards_fts, events_fts and documents_fts tables, and the two rankings are merged with Reciprocal Rank Fusion. The reason for the hybrid is straightforward: a vector index is good at semantic similarity and bad at exact keyword lookup, and for a tool whose job is to find a specific ticket or a specific error string, exact match is often what you want.

Coherence is the cross-platform search on top of that. It traces any person, ticket or pull request across all platforms using the hybrid search, and it adds AI-generated narratives so the result is a readable account rather than a list of matches.

Corpus handles documents, and the constraint on it is worth knowing. You can drop a PDF, DOCX, Markdown, text, CSV, JSON or HTML file anywhere in the app, and Laya parses, chunks, embeds and indexes it locally. Files are read in place and never copied, and an AI summary is written at ingest. Chat answers from your documents with page-level citations, cards show the documents that mention their ticket or pull request, and Coherence traces include linked documents. The same read tools are exposed over MCP, so an external agent can query your corpus with the same access the app has.

Reading in place rather than copying is a deliberate privacy choice with a practical consequence. Your documents stay where they are, and the index is derived, so deleting the source leaves a stale index entry rather than a copied file lying around. It also means the corpus cannot survive the original file, which matters if you were planning to treat Laya as a document store.

Cost control and personas are what make it usable daily

Two features decide whether a tool like this gets used every day or abandoned after a week.

The first is budget tracking. Laya monitors LLM costs by feature, with the features named as Pulse, Omni, Chat, Coherence and Corpus, and applies monthly caps with automatic pause when limits are reached. Running on agent inference backends adds a second mechanism, a window-based usage budget that pauses ingestion as an agent's rolling quota nears its limit and resumes automatically when the window resets. That distinction matters: with API keys you are billed per token and can watch a dashboard, but with a subscription quota you can lose the ability to classify events entirely, which is why ingestion has to pause rather than the whole application.

The second is the multi-persona brain. Events are routed to specialised personas, with Engineer, Comms, Ops, Sales, HR and Finance named, each with domain-specific tools and prompts, and every notification is prioritised by AI. A single global classifier treats every message the same way. Personas let the routing reflect what the event actually is, so a comms message and a failing build do not compete for the same attention.

Around those sit the features that make the daily loop work: a Daily Briefing summarising overnight activity, pending cards and today's calendar; a chat sidebar where you can ask about events, projects, context and Corpus documents, and create, edit or delete filter, classification and processing rules directly from the conversation; Omni, a rolling cross-platform summary answering where am I right now, with four temporal layers of Attention, Recent, Period and Milestone and progressive AI compression; and Bookmarks to pin important cards regardless of date or status.

The stack, the ports, and the release pace

The tech stack table is a good summary of the engineering choices, and the project structure tells you the server port.

The desktop shell is Tauri v2 in Rust, the front end is Svelte 5 with runes, Skeleton UI and Tailwind CSS v4, the backend is Python 3.10 or newer with FastAPI and asyncio, and the LLM interface is LiteLLM. The integration gateway is n8n running as local Node.js on port 45678, the structured storage is SQLite accessed asynchronously through aiosqlite in WAL mode, and vector storage is ChromaDB as an embedded PersistentClient. Embeddings come from ONNX, built into ChromaDB, or from sentence-transformers optionally.

The project structure block shows the backend entry point running uvicorn on port 8420, with a config.py handling settings, paths and agent detection, and an api/ directory holding REST and WebSocket endpoints across 28 routers. So a local run means two services on fixed ports, n8n on 45678 and the engine on 8420, and the front end talks to the latter.

The release history is fast. The three most recent tags are v2.2.1 from 2026-10-20, v2.1.1 from 2026-10-19 and v2.1.0 from 2026-10-19, three releases in two days. The repository is not archived and the last push was on 2026-10-20, the same day as the newest tag. The licence is Apache-2.0, with the LICENSE and NOTICE files at the root, and there is a SECURITY.md alongside a CLAUDE.md for working with the project.

A feature list this long also carries risk, and the two-day release cadence means the surface is moving quickly enough that the documentation may lag behind a given release.

Editorial conclusion

Laya suits an individual or a small team drowning in notifications who wants a triage layer that runs on their own machine with Ollama or LM Studio, and who is willing to wire up API keys for the tools they want aggregated. It does not suit a regulated environment where notification content cannot leave the machine without review, and it does not suit anyone wanting a finished product, since it is a large surface with a v2 line still settling after the 2.2.1 release. Before trying it, run the n8n integration gateway locally on port 45678, start the Python engine on port 8420, and decide which model backend each stage will use before you connect a real workspace.

Frequently asked questions

What is Laya?

Laya is an open-source, local-first AI notification command center. It intercepts events from professional tools, has LLM-powered agents do autonomous research and stage actions, and presents ready-to-approve action cards so the answer exists before you open the notification.

Which services can Laya aggregate?

Gmail, Slack, GitHub, Bitbucket, Jira, Linear, Notion, Outlook for email and calendar, and Google Calendar. The readme also mentions Calendars generally in the list of tools it intercepts events from.

Can Laya run entirely on local models?

Yes. Ollama and LM Studio are listed as the local options, alongside Claude, GPT, Gemini, and Llama or any OpenAI-compatible endpoint through LiteLLM. It can also run the pipeline on an installed CLI agent's own quota using a model of the form agent/<id>/<model>.

How does Laya handle LLM costs?

It monitors LLM costs by feature, with Pulse, Omni, Chat, Coherence and Corpus named, and applies monthly caps with automatic pause when limits are reached. On agent inference backends a separate window-based budget pauses ingestion as a rolling quota nears its limit and resumes when the window resets.

What does Laya do with documents?

You can drop a PDF, DOCX, Markdown, text, CSV, JSON or HTML file anywhere in the app and Laya parses, chunks, embeds and indexes it locally. Files are read in place and never copied, chat answers cite pages, and the same read tools are exposed over MCP.

Official sources

  1. aayushch/laya on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aayushch-laya.svg)](https://hysenlabs.com/projects/aayushch-laya)

Was this useful?