Knowledge Graph
Browse, search, and manage Owlat's typed organizational knowledge — the 7 entry types, source attribution, confidence decay, relations, and how entries are extracted from mail.
The Knowledge Graph is Owlat's typed store of organizational knowledge — customer preferences, decisions, commitments, and relationships, captured as searchable entries that the AI agent can draw on. Instead of a write-only log, it's a living set of facts that each carry a confidence score, decay over time, and can be linked to contacts, conversation threads, and one another. You browse and search it from the dashboard, and you can add entries by hand.
What the Knowledge Graph is (and the ai.knowledge flag)
Every entry is a small, typed piece of knowledge: a fact, a decision, an event, a preference, a goal, a relationship, or an action item. Each one records what the knowledge is, where it came from, how confident Owlat is in it, and who or what it relates to.
The graph is both a browsing and authoring surface and a live input to drafting: the Knowledge Graph page in the dashboard is where you and your team search and review what Owlat knows, and where you add entries by hand. When the AI agent drafts a reply, its context-retrieval step also searches the graph (contact-scoped) and injects the matching entries into the drafting prompt — so knowledge you capture is fed back into the agent's replies today.
The whole feature sits behind the Knowledge graph feature flag (ai.knowledge), which is off by default and depends on the master AI features flag (ai). Until an operator enables both, the knowledge search query returns nothing. See Feature flags for how to turn them on (you'll need an LLM provider configured, since the backfill extraction and embeddings call your model).
Owlat runs one organization per deployment, so there is a single knowledge graph for the whole workspace. There's no per-team or per-org partitioning — every entry belongs to this deployment.
Entry types, sources, confidence and tags
The seven entry types
Each entry has exactly one type. The type controls its icon, its colour in the UI, and — importantly — how fast its confidence decays (see Confidence decay and expiry).
| Type | What it captures | Example |
|---|---|---|
| Fact | Verifiable information about a person, company, or thing | "Acme Corp is on the Enterprise plan" |
| Decision | A choice that was made, with reasoning | "Extended Acme's trial by two weeks (approved by Sarah)" |
| Event | Something that happened at a point in time | "Met Acme's CTO at the conference on March 5" |
| Preference | How someone likes things done | "Acme prefers email over phone for support" |
| Goal | An objective someone is working toward | "Acme wants to launch their email program by September" |
| Relationship | A connection between people | "Alice at Acme reports to Bob" |
| Action Item | A commitment or task mentioned in conversation | "Send Acme the updated proposal by Friday" |
Source attribution
Every entry records where it came from. The source appears in the entry's detail sidebar, and when the source is a conversation thread you get a View source thread link straight into the inbox.
| Source | Meaning |
|---|---|
| Captured from an email message | |
| Chat | Captured from a chat message |
| Manual | Created by hand in the dashboard |
| File | Captured from a file |
| AI Extracted | Pulled out of a message by the extraction pipeline |
Confidence and tags
- Confidence is a 0–100% score of how reliable the knowledge is. It's shown as a coloured bar on the entry — green at 70%+, amber from 40%, red below — and it drifts down over time unless re-validated.
- Tags are free-form labels (for example
important,customer,q1-2026) for grouping and skimming. They're shown as chips on the entry. - Entries can also be linked to contacts and to a conversation thread. Linked contacts appear in the detail sidebar with links to each contact profile.
Browsing and searching entries
Open Knowledge Graph from the dashboard. The page gives you a search box, a row of type tabs, and the entry list.
- Type tabs — All plus one tab per entry type. Selecting a type filters the list to that type (newest first). The sidebar shows a legend of every type with its icon.
- Search — type into the search box and Owlat runs a full-text search over entry titles and content. The search respects the active type tab, so you can search within just facts, just decisions, and so on.
Click any entry to open its detail page, which shows the full content, tags, the confidence bar, source, created/updated/expiry dates, linked contacts, and any relations.
Knowledge entries linked to a contact also surface against that contact elsewhere in the product. That lookup goes through an indexed contact→entry junction, so it returns all entries for that contact — the complete history, not just the most recent — and stays efficient even on a very large graph.
Creating entries manually
You don't have to wait for extraction — you can write entries yourself. Click Create Entry (top-right of the Knowledge Graph page, or Create First Entry from the empty state) and fill in the form:
Pick a type
Choose one of the seven entry types from the Type dropdown.
Write a title and content
Give the entry a short, descriptive Title and the detailed knowledge in Content. Both are required.
Set the source
The Source defaults to Manual for hand-authored entries; you can change it if you're recording where the knowledge actually originated.
Set confidence
Drag the Confidence slider (0–100%, default 80%) to reflect how sure you are.
Add tags and an expiry (optional)
Enter comma-separated Tags, and optionally set Expires in a number of days — after which the entry is cleaned up automatically (see expiry).
Saving takes you straight to the new entry's detail page. Any signed-in member of the workspace can create entries.
Relations between entries (typed edges)
Entries can be connected by typed edges, and the entry detail page renders an entry's relations in both directions — incoming and outgoing. The supported relation types are:
| Relation | Meaning |
|---|---|
supports | One entry provides evidence for another |
contradicts | One entry conflicts with another |
supersedes | One entry replaces another with newer information |
relates_to | A general association |
causes | A causal link |
blocks | One entry prevents another |
To link two entries, open an entry's detail page, click Add relation in the Relations card, pick the edge type, search for the target entry, and save. The new edge appears immediately on both entries — outgoing on this one, incoming on the other. Hover any relation and click the × to remove it. Any signed-in member of the workspace can curate relations; a relation is automatically removed when either of its two entries is deleted or expires.
You author the semantic relations by hand today, while generic relates_to edges are generated automatically. The agent reasoning that would automatically infer supports / contradicts / supersedes edges from the content of new entries is part of the Knowledge Graph vision and is not yet wired up. The extraction pipeline already auto-creates generic relates_to edges between entries from the same message or conversation thread (a deterministic structural linker); what is not yet wired up is the LLM reasoning that would infer the semantic supports / contradicts / supersedes edges from entry content.
How knowledge gets extracted
Extraction happens in two places: live, as inbound mail is processed, and a one-time backfill that seeds the graph from your existing history.
As each inbound message moves through the inbox processing lifecycle, once it's been classified Owlat mines it for organizational knowledge. The extraction fires exactly once per message, is idempotent, and runs best-effort (a failure on one message never blocks the message's own processing). New mail therefore grows the graph as it arrives.
The backfill is a first-run job that seeds the graph from your existing mail so the agent has historical context from day one:
- It is triggered once, on the first time the AI agent is switched on (the
false → trueedge of the AI agent toggle). Turning the agent off and on again does not re-run it. - It walks the deployment's existing inbound messages in batches and runs each through the LLM extractor, which produces typed entries with
AI Extractedas their source. - It is idempotent: a message that's already been extracted is skipped, so the job is safe to resume.
- Very short messages and greetings are skipped, and extraction failures on individual messages are tolerated rather than aborting the whole run.
You watch and control the backfill from the AI Agent settings page (apps/web/app/pages/dashboard/settings/agent.vue), which shows live progress — scanned, extracted, skipped, and error counts — and a Cancel action while it's running. Cancelling is admin-only and stops the run cleanly at the next batch.
The extractor makes a single structured LLM call per message, embeds each resulting entry, and stores it. It does not itself deduplicate near-identical entries (a separate daily job handles that — see Confidence decay and expiry) or check for contradictions. It does hand the freshly-stored batch to a deterministic structural linker that auto-creates generic relates_to edges (as noted under Relations); the LLM-inferred semantic edges remain on the roadmap. Semantic ("vector") search over knowledge is live: the agent's contact-scoped knowledge retrieval runs hybrid vector + full-text search fused with reciprocal-rank fusion, returning true nearest-neighbour matches. Full-text search and browse-by-type remain the live retrieval paths in the dashboard UI.
Confidence decay and expiry
The graph is deliberately not append-only. A scheduled maintenance job runs every 24 hours and does two things to every batch of entries it visits:
- Expiry cleanup — entries past their
expiresAtdate are deleted (along with their relations). This is how the optional Expires in value you set on an entry takes effect. - Confidence decay — each entry's confidence is reduced based on how long it's been since it was last validated and a per-type decay rate. Frequently-recalled entries decay slightly slower (a usage-recency boost). Confidence never drops below a floor of 10%.
A second daily job dedup-merges near-identical entries for the same contact, keeping the graph from accumulating duplicates as new mail is mined.
Different knowledge ages at different speeds — a customer's plan changes far less often than a quarterly goal — so each type decays at its own rate:
| Type | Decay per day | Why |
|---|---|---|
| Fact | 0.5% | Facts change infrequently (~90-day half-life) |
| Decision | 0.2% | Decisions persist unless explicitly reversed |
| Event | None | Historical events don't become less true |
| Preference | 1.5% | Preferences evolve over time (~30-day half-life) |
| Goal | 3% | Goals have deadlines and shift (~14-day half-life) |
| Relationship | 1% | Org structures change |
| Action Item | 5% | Commitments resolve quickly (~7-day half-life) |
The intent is for confidence to be raised when knowledge is validated — for example when the agent uses an entry and a human approves the resulting reply. That boost isn't implemented yet, so today confidence only decays (or holds steady, for events). See the Knowledge Graph vision for the full picture.