Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .cursor/skills/pre-pr-review-fixes/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
name: pre-pr-review-fixes
description: Fix pull request feedback before opening or updating a PR. Use when the user asks to address reviewer comments, clean up docs/style issues before PR, or apply repeated feedback patterns (wording, headings, spacing, capitalization, markdown tables, and consistency fixes).
disable-model-invocation: true
---

# Pre-PR Review Fixes

Use this skill to systematically apply reviewer feedback before creating or updating a PR.

## When to use

- User asks to "fix PR comments" or "address review feedback"
- User asks to "prepare this for PR" or "clean this up before PR"
- Same reviewer repeatedly flags style/structure issues across multiple files

## Why this is a skill (not a rule)

- This workflow is task-specific and should run on demand.
- A global rule would trigger too often and add overhead to unrelated tasks.
- Skills are easier to extend with new reviewer patterns over time.

## Inputs expected

- PR URL or PR number
- Reviewer name(s) to prioritize (if applicable)
- Optional scope limits (files/folders)

## Workflow

1. Fetch review feedback
- Pull top-level review summaries and inline comments.
- Filter to actionable reviewer comments (ignore bot noise unless requested).
2. Build an action list
- Group comments by file and section.
- Normalize into concrete edits (wording, formatting, structure, examples, links).
- Deduplicate repeated comments and mark global patterns to apply throughout.
3. Apply fixes in files
- Edit only requested/scope-relevant files.
- Keep existing technical intent; change style/clarity unless behavior changes are requested.
4. Validate
- Run lints on edited files.
- Re-read changed sections to ensure comment intent is fully addressed.
5. Report back
- List updated files.
- Map key edits to reviewer themes.
- Call out any comments that were ambiguous or not applicable.

## Common docs fixes checklist

- Add a context paragraph before a heading/table when needed
- Avoid bold text as faux headings; use real heading levels
- Use italics (not bold) for light emphasis when requested
- Remove extra blank lines (keep one empty line between blocks)
- Fix incomplete/ambiguous phrasing
- Standardize reference style: "For ..., refer to [Link](url)."
- Replace vague endings like `etc.` with explicit wording
- Keep capitalization consistent across bullets/tables
- Ensure markdown tables are valid and readable

## Comment triage rules

- **Apply directly:** explicit suggestions and clear style requests
- **Apply throughout:** repeated reviewer guidance across multiple files
- **Ask user before changing:** unclear product intent, technical behavior changes, or conflicting reviewer guidance
- **Skip with note:** non-actionable comments (for example, design critique with no available source/update path)

## Output format to user

Use this structure:

1. Files changed
2. What was fixed (by reviewer theme)
3. What was not changed (and why)
4. Validation result (lint/tests run)

## Extension notes

To extend this skill, add:

- A `patterns.md` file with reviewer-specific conventions
- A `commands.md` file with reusable `gh` queries for PR feedback
- Team-specific wording conventions for docs pages
5 changes: 5 additions & 0 deletions content/docs/agents/add-connect-components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: "Add Connect Components"
pageTitle: 'Novu Agents Add Connect Components'
description: 'Add Connect UI components so users can link accounts and channels to your agent.'
---
5 changes: 5 additions & 0 deletions content/docs/agents/deploy-your-agent.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: "Deploy Your Agent"
pageTitle: 'Novu Agents Deployment'
description: 'Deploy your Novu Agent to production environments.'
---
184 changes: 184 additions & 0 deletions content/docs/agents/get-started/core-concepts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
title: "Core Concepts"
pageTitle: 'Core Concepts'
description: "Understand the core entities, lifecycle, and building blocks inside Novu's Agent Communication Infrastructure implementation."
icon: Blocks
---

import { HomeIcon } from 'lucide-react';

Check notice on line 8 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L8

[Google.Semicolons] Use semicolons judiciously.
Raw output
{"message": "[Google.Semicolons] Use semicolons judiciously.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 8, "column": 40}}}, "severity": "INFO"}


Novu for Agents is built around a set of concepts, these concepts are how Novu implements Agent Communication Infrastructure (ACI).

Check notice on line 11 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L11

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 11, "column": 17}}}, "severity": "INFO"}

Check warning on line 11 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L11

[write-good.Passive] 'is built' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is built' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 11, "column": 17}}}, "severity": "WARNING"}

Check notice on line 11 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L11

[Google.Passive] In general, use active voice instead of passive voice ('is built').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is built').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 11, "column": 17}}}, "severity": "INFO"}

Check notice on line 11 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L11

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 11, "column": 67}}}, "severity": "INFO"}

Check notice on line 11 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L11

[Google.Parens] Use parentheses judiciously.
Raw output
{"message": "[Google.Parens] Use parentheses judiciously.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 11, "column": 126}}}, "severity": "INFO"}

## The mental model

Novu for Agents connects messaging platform to your agent logic through a standard communication layer. This communication can be bi-directional, a user can message your agent, and your agent can proactively reach out to a user.

Check notice on line 15 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L15

[write-good.E-Prime] Try to avoid using 'be'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'be'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 15, "column": 128}}}, "severity": "INFO"}

When a user sends a message or interacts with your agent from a connected platform, the inbound flow works like this. Novu receives it, resolves identity and conversation state, and forwards the full context to your server. Your agent processes the message and replies, then Novu delivers the response back to the platform. The flow works like this:

Here's what happens at each step:

Check notice on line 19 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L19

[write-good.E-Prime] Try to avoid using 'Here's'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'Here's'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 19, "column": 1}}}, "severity": "INFO"}

### Receive and identify

Novu receives the platform webhook and normalizes it into a standard format. It matches the platform user, for example, a Slack user ID to a Novu subscriber. Known users get their full profile attached, while unknown users are tracked as anonymous until identity is resolved.

Check notice on line 23 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L23

[Google.Passive] In general, use active voice instead of passive voice ('are tracked').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are tracked').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 23, "column": 224}}}, "severity": "INFO"}

Check warning on line 23 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L23

[write-good.Passive] 'are tracked' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'are tracked' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 23, "column": 224}}}, "severity": "WARNING"}

Check notice on line 23 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L23

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 23, "column": 224}}}, "severity": "INFO"}

Check warning on line 23 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L23

[write-good.Passive] 'is resolved' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is resolved' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 23, "column": 264}}}, "severity": "WARNING"}

Check notice on line 23 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L23

[Google.Passive] In general, use active voice instead of passive voice ('is resolved').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is resolved').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 23, "column": 264}}}, "severity": "INFO"}

Check notice on line 23 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L23

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 23, "column": 264}}}, "severity": "INFO"}

### Load conversation

Novu creates a new conversation, if this is the first message or loads the existing one. The message history, metadata, and subscriber information are assembled into a single context object.

Check notice on line 27 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L27

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 27, "column": 42}}}, "severity": "INFO"}

Check notice on line 27 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L27

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 27, "column": 148}}}, "severity": "INFO"}

Check warning on line 27 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L27

[write-good.Passive] 'are assembled' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'are assembled' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 27, "column": 148}}}, "severity": "WARNING"}

Check notice on line 27 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L27

[Google.Passive] In general, use active voice instead of passive voice ('are assembled').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are assembled').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 27, "column": 148}}}, "severity": "INFO"}

### Your handler

Novu calls your handler with the complete context: the message, conversation history, subscriber, and platform details. You process it with your LLM, business logic, or whatever system you've chosen, and call `ctx.reply()` to respond.

Check notice on line 31 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L31

[Google.Acronyms] Spell out 'LLM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'LLM', if it's unfamiliar to the audience.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 31, "column": 146}}}, "severity": "INFO"}

### Deliver and persist

Novu delivers the reply to the correct thread on the platform, persists it in the conversation history, and records the activity. Every message, signal, and status change is visible in the dashboard.

Check notice on line 35 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L35

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 35, "column": 172}}}, "severity": "INFO"}

Your server never talks to the platform directly. It receives a context object and returns a reply, Novu handles everything else.

## Key entities

Four core entities make up the system.

### Agents

An agent is the entity you create in Novu when you want to expose agent logic through one or more communication providers.

Check notice on line 45 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L45

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 45, "column": 10}}}, "severity": "INFO"}

Each agent has a name, an identifier, and a set of event handlers that define how your application responds to conversation events. An agent can be connected to one or more providers, such as Slack, Microsoft Teams, WhatsApp, or email.

Check warning on line 47 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L47

[write-good.Passive] 'be connected' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'be connected' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 47, "column": 146}}}, "severity": "WARNING"}

Check notice on line 47 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L47

[write-good.E-Prime] Try to avoid using 'be'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'be'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 47, "column": 146}}}, "severity": "INFO"}

Check notice on line 47 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L47

[Google.Passive] In general, use active voice instead of passive voice ('be connected').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be connected').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 47, "column": 146}}}, "severity": "INFO"}

The agent doesn't define your AI model, prompts, tools, or business logic. It gives Novu a bridge to the application code where that logic runs. The provider handles where the user communicates. The agent handles how your application responds.

### Providers connection

A provider connection connects an agent to a messaging platform. Providers are the surfaces where users interact with your agent. A provider connection gives Novu the credentials and configuration needed to receive events from that provider and deliver responses back to it.

Check notice on line 53 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L53

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 53, "column": 76}}}, "severity": "INFO"}

Each provider has its own setup flow and platform capabilities. Some providers support reactions, typing indicators, attachments, rich cards, or message editing. Others may support only a subset of those behaviors. Novu normalizes provider events before passing them to your agent handler, so your code works with a consistent interface instead of provider-specific webhook payloads.

This is what makes the architecture channel agnostic, you won't see anything related to Slack or WhatsApp or email in your agent code. Novu takes care of translating messages downstream to each provider's specific format and capabilities.

Check notice on line 57 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L57

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 57, "column": 6}}}, "severity": "INFO"}

### Conversations

A conversation is the stateful thread where communication happens. When a user sends a message from a connected provider, Novu creates a new conversation or loads the existing one for that thread. The conversation includes the message history, metadata, participants, status, and platform context needed to process the next interaction.

Check notice on line 61 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L61

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 61, "column": 16}}}, "severity": "INFO"}

A conversation can include multiple participants. The agent is one participant in the conversation, but it is not the conversation itself. This distinction matters when you inspect conversations in the dashboard or build agent behavior around conversation state. A Slack thread, email thread, or other provider-specific thread maps to a conversation in Novu automatically.

Check warning on line 63 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L63

[write-good.TooWordy] 'multiple' is too wordy.
Raw output
{"message": "[write-good.TooWordy] 'multiple' is too wordy.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 63, "column": 28}}}, "severity": "WARNING"}

Check notice on line 63 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L63

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 63, "column": 61}}}, "severity": "INFO"}

Check warning on line 63 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L63

[write-good.TooWordy] 'it is' is too wordy.
Raw output
{"message": "[write-good.TooWordy] 'it is' is too wordy.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 63, "column": 105}}}, "severity": "WARNING"}

Check notice on line 63 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L63

[Google.Contractions] Use 'it's' instead of 'it is'.
Raw output
{"message": "[Google.Contractions] Use 'it's' instead of 'it is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 63, "column": 105}}}, "severity": "INFO"}

Check notice on line 63 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L63

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 63, "column": 108}}}, "severity": "INFO"}

The conversations follow a simple lifecycle, a conversation starts as active when the first message arrives. Messages, actions, and reactions continue updating the conversation while it remains active. The conversation can be marked as resolved when the agent calls the resolve signal. When a conversation is resolved, the resolve handler fires and an optional summary is stored.

Check notice on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[write-good.E-Prime] Try to avoid using 'be'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'be'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 224}}}, "severity": "INFO"}

Check warning on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[write-good.Passive] 'be marked' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'be marked' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 224}}}, "severity": "WARNING"}

Check notice on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[Google.Passive] In general, use active voice instead of passive voice ('be marked').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be marked').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 224}}}, "severity": "INFO"}

Check notice on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 307}}}, "severity": "INFO"}

Check warning on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[write-good.Passive] 'is resolved' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is resolved' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 307}}}, "severity": "WARNING"}

Check notice on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[Google.Passive] In general, use active voice instead of passive voice ('is resolved').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is resolved').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 307}}}, "severity": "INFO"}

Check notice on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 370}}}, "severity": "INFO"}

Check warning on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[write-good.Passive] 'is stored' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is stored' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 370}}}, "severity": "WARNING"}

Check notice on line 65 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L65

[Google.Passive] In general, use active voice instead of passive voice ('is stored').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is stored').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 65, "column": 370}}}, "severity": "INFO"}

If a user sends a new message after a conversation has been resolved, the conversation automatically reopens so the interaction can continue.

Check notice on line 67 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L67

[write-good.E-Prime] Try to avoid using 'been'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'been'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 67, "column": 56}}}, "severity": "INFO"}

Check warning on line 67 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L67

[write-good.Passive] 'been resolved' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'been resolved' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 67, "column": 56}}}, "severity": "WARNING"}

Check notice on line 67 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L67

[Google.Passive] In general, use active voice instead of passive voice ('been resolved').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('been resolved').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 67, "column": 56}}}, "severity": "INFO"}

### Participants and subscriber identity

Participants are the people, agents, or systems involved in a conversation. When a user messages your agent from a provider, Novu tries to resolve that platform user to a known subscriber.

Check notice on line 71 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L71

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 71, "column": 14}}}, "severity": "INFO"}

- If a match exists, then the handler receives subscriber information such as the subscriber ID, name, or email.

Check warning on line 73 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L73

[Novu.BulletStyle] Prefer '*' over '-' for bullet points (ignore inside code fences).
Raw output
{"message": "[Novu.BulletStyle] Prefer '*' over '-' for bullet points (ignore inside code fences).", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 73, "column": 1}}}, "severity": "WARNING"}
- If no match exists, then the user is tracked as a platform user and your handler should account for cases where subscriber data is unavailable.

Check warning on line 74 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L74

[Novu.BulletStyle] Prefer '*' over '-' for bullet points (ignore inside code fences).
Raw output
{"message": "[Novu.BulletStyle] Prefer '*' over '-' for bullet points (ignore inside code fences).", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 74, "column": 1}}}, "severity": "WARNING"}

Check notice on line 74 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L74

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 74, "column": 37}}}, "severity": "INFO"}

Check warning on line 74 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L74

[write-good.Passive] 'is tracked' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is tracked' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 74, "column": 37}}}, "severity": "WARNING"}

Check notice on line 74 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L74

[Google.Passive] In general, use active voice instead of passive voice ('is tracked').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is tracked').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 74, "column": 37}}}, "severity": "INFO"}

Once identity is resolved later, they are upgraded to a full subscriber and future messages include their subscriber data.

Check notice on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 15}}}, "severity": "INFO"}

Check notice on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[Google.Passive] In general, use active voice instead of passive voice ('is resolved').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is resolved').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 15}}}, "severity": "INFO"}

Check warning on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[write-good.Passive] 'is resolved' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is resolved' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 15}}}, "severity": "WARNING"}

Check notice on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[Google.Contractions] Use 'they're' instead of 'they are'.
Raw output
{"message": "[Google.Contractions] Use 'they're' instead of 'they are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 34}}}, "severity": "INFO"}

Check notice on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[Google.Passive] In general, use active voice instead of passive voice ('are upgraded').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are upgraded').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 39}}}, "severity": "INFO"}

Check notice on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 39}}}, "severity": "INFO"}

Check warning on line 76 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L76

[write-good.Passive] 'are upgraded' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'are upgraded' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 76, "column": 39}}}, "severity": "WARNING"}

Subscriber identity helps your agent personalize responses, look up account details, or decide whether a conversation should be escalated. Identity resolution is provider-aware, a Slack user, or email sender may each have different identifiers at the provider level that Novu resolves to a single subscriber.

Check notice on line 78 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L78

[write-good.E-Prime] Try to avoid using 'be'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'be'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 78, "column": 126}}}, "severity": "INFO"}

Check warning on line 78 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L78

[write-good.Passive] 'be escalated' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'be escalated' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 78, "column": 126}}}, "severity": "WARNING"}

Check notice on line 78 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L78

[Google.Passive] In general, use active voice instead of passive voice ('be escalated').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be escalated').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 78, "column": 126}}}, "severity": "INFO"}

Check warning on line 78 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L78

[Novu.SentenceLength] Sentences should not exceed 25 words; this one has 26.
Raw output
{"message": "[Novu.SentenceLength] Sentences should not exceed 25 words; this one has 26.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 78, "column": 140}}}, "severity": "WARNING"}

Check notice on line 78 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L78

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 78, "column": 160}}}, "severity": "INFO"}

## The bridge surface

Novu exposes a consistent set of building blocks to your agent code. These are the same regardless of which provider the message came from or what brain you've plugged in.

Check notice on line 82 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L82

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 82, "column": 76}}}, "severity": "INFO"}

### Event handlers

Event handlers are functions that respond to events in a conversation. Your agent can respond to four event types:

Check notice on line 86 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L86

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 86, "column": 16}}}, "severity": "INFO"}

| Handler | When it runs | Common use case |
|---------|-------------|-----------------|
| `onMessage` | A user sends a message in the conversation | Process the message and reply |
| `onAction` | A user clicks a button or selects a value in an interactive card | Handle form submissions, button clicks, or dropdown selections |
| `onReaction` | A user adds or removes a reaction | Capture feedback or trigger a follow-up |
| `onResolve` | The conversation is marked as resolved | Clean up state, log analytics, or send a summary |

Check warning on line 93 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L93

[write-good.Passive] 'is marked' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'is marked' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 93, "column": 34}}}, "severity": "WARNING"}

Check notice on line 93 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L93

[Google.Passive] In general, use active voice instead of passive voice ('is marked').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is marked').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 93, "column": 34}}}, "severity": "INFO"}

Check notice on line 93 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L93

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 93, "column": 34}}}, "severity": "INFO"}

Handlers are where the communication layer connects to your application logic. For example, an `onMessage` handler receives the user's message, passes the conversation context to an LLM or custom function, and sends the response back through Novu.

Check notice on line 95 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L95

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 95, "column": 10}}}, "severity": "INFO"}

Check notice on line 95 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L95

[Google.Acronyms] Spell out 'LLM', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'LLM', if it's unfamiliar to the audience.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 95, "column": 183}}}, "severity": "INFO"}

### Context object

Each event handler receives a context object. The context object gives your handler the information it needs to understand the current event and respond to it. Depending on the event type, it can include:
* The incoming message.
* The current conversation state and metadata.
* The resolved subscriber (when available).

Check notice on line 102 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L102

[Google.Parens] Use parentheses judiciously.
Raw output
{"message": "[Google.Parens] Use parentheses judiciously.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 102, "column": 27}}}, "severity": "INFO"}
* Recent conversation history.
* Provider information.
* Platform-specific details, such as thread or channel identifiers.
* Methods for replying, updating metadata, triggering workflows, or resolving the conversation.

The context object is the single interface between Novu's communication layer and your agent logic. Your code doesn't need to talk directly to Slack, Microsoft Teams, WhatsApp, or email, everything flows through the context.

Check notice on line 108 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L108

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 108, "column": 20}}}, "severity": "INFO"}

### Replies and interactions

A reply sends a message back into the conversation. Agents can reply with different content types depending on the provider and platform capabilities: plain text, markdown with files, or interactive cards.

Interactive cards let your agent send structured responses with components such as buttons, dropdowns, links, and text inputs. When a user interacts with a card, the `onAction` handler fires with the action ID and selected value.

Replies are user-facing, use them when the agent needs to communicate something back to the participant in the conversation.

Check notice on line 116 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L116

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 116, "column": 9}}}, "severity": "INFO"}

### Signals

Signals are system-facing actions your agent can perform during a conversation. Use signals when your handler needs to update state, trigger another process, or close a conversation, without necessarily sending another message to the user.

Check notice on line 120 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L120

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 120, "column": 9}}}, "severity": "INFO"}

| Signal | What it does |
|--------|-------------|
| Metadata | Stores key-value data on the conversation that persists across messages |
| Trigger | Starts a Novu workflow from within the conversation |
| Resolve | Marks the conversation as resolved with an optional summary |

A useful way to think about the difference: replies communicate with the user, signals update the system around the conversation. A single handler invocation can do both, reply to the user, store a sentiment score in metadata, trigger an escalation workflow, and resolve the conversation.

Signals aren't sent immediately when you call them. They're queued in memory and batched together with your next reply call in a single request. If your handler finishes without calling reply handler, any pending signals are still sent automatically.

Check notice on line 130 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L130

[write-good.E-Prime] Try to avoid using 'aren't'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'aren't'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 130, "column": 9}}}, "severity": "INFO"}

Check notice on line 130 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L130

[write-good.E-Prime] Try to avoid using 'They're'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'They're'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 130, "column": 53}}}, "severity": "INFO"}

Check notice on line 130 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L130

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 130, "column": 222}}}, "severity": "INFO"}

## Conversations and workflows

ACI's conversation model and Novu's workflows are designed to work together. A conversation can trigger a workflow.

Check warning on line 134 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L134

[write-good.Passive] 'are designed' may be passive voice. Use active voice if you can.
Raw output
{"message": "[write-good.Passive] 'are designed' may be passive voice. Use active voice if you can.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 134, "column": 47}}}, "severity": "WARNING"}

Check notice on line 134 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L134

[Google.Passive] In general, use active voice instead of passive voice ('are designed').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are designed').", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 134, "column": 47}}}, "severity": "INFO"}

Check notice on line 134 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L134

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 134, "column": 47}}}, "severity": "INFO"}

For example, a user chatting with an agent in Slack asks it to prepare a report and send it via email. The agent calls a trigger function to fire a Novu workflow that handles the email delivery using the same workflow infrastructure your team might already have in place.

Check warning on line 136 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L136

[Novu.SentenceLength] Sentences should not exceed 25 words; this one has 28.
Raw output
{"message": "[Novu.SentenceLength] Sentences should not exceed 25 words; this one has 28.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 136, "column": 104}}}, "severity": "WARNING"}

A workflow can convert into a conversation. For example, you send a weekly digest notification to a user's email. The user replies to that email with a follow-up question, and that reply enters ACI as a new conversation with the agent. What started as a one-directional notification becomes a back-and-forth exchange.

This connection means ACI is not a replacement for Novu's workflow system — it's an extension of it. The structured, predictable nature of transactional workflows and the open-ended, freeform nature of agent conversations are complementary. The value is in the combination of the two within the same platform.

Check notice on line 140 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L140

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 140, "column": 27}}}, "severity": "INFO"}

Check notice on line 140 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L140

[Google.Contractions] Use 'isn't' instead of 'is not'.
Raw output
{"message": "[Google.Contractions] Use 'isn't' instead of 'is not'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 140, "column": 27}}}, "severity": "INFO"}

Check failure on line 140 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L140

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 140, "column": 74}}}, "severity": "ERROR"}

Check notice on line 140 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L140

[write-good.E-Prime] Try to avoid using 'it's'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'it's'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 140, "column": 77}}}, "severity": "INFO"}

Check notice on line 140 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L140

[write-good.E-Prime] Try to avoid using 'are'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'are'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 140, "column": 223}}}, "severity": "INFO"}

## How the Concepts Work Together

Check warning on line 142 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L142

[Google.Headings] 'How the Concepts Work Together' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'How the Concepts Work Together' should use sentence-style capitalization.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 142, "column": 4}}}, "severity": "WARNING"}

Here is the end-to-end flow when a user messages your agent:

Check notice on line 144 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L144

[write-good.E-Prime] Try to avoid using 'is'.
Raw output
{"message": "[write-good.E-Prime] Try to avoid using 'is'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 144, "column": 6}}}, "severity": "INFO"}

1. A user sends a message to your agent from Slack.
2. Novu receives the Slack event through the provider connection.
3. Novu maps the Slack thread to a conversation and resolves the platform user to a subscriber when possible.
4. Novu calls the agent's `onMessage` handler with the context object.
5. Your handler passes the message and conversation context to your agent logic.
6. Your agent logic decides what should happen next.
7. Your handler sends a reply, emits signals, or both.
8. Novu delivers the reply back to the Slack thread.
9. Novu records the messages, participants, metadata, signals, and conversation status.

The same agent logic works across all connected providers because Novu handles the provider-specific communication layer. Connecting a new provider does not require changing your agent code.

Check notice on line 156 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L156

[Google.Contractions] Use 'doesn't' instead of 'does not'.
Raw output
{"message": "[Google.Contractions] Use 'doesn't' instead of 'does not'.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 156, "column": 149}}}, "severity": "INFO"}

## Next steps

Now that you understand the core concepts, continue with:

<Cards>
<Card
icon={<HomeIcon />}
href="/agents/getting-started/quickstart"
title="Quickstart"
>
Create your first agent, connect a provider, and send a message.
</Card>
<Card
icon={<HomeIcon />}
href="/agents/agent-bridge/agent-definition"

Check warning on line 172 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L172

[Novu.SentenceLength] Sentences should not exceed 25 words; this one has 29.
Raw output
{"message": "[Novu.SentenceLength] Sentences should not exceed 25 words; this one has 29.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 172, "column": 5}}}, "severity": "WARNING"}
title="Agent bridge"
>
Deep dive into defining agents, event handlers, context, replies, and signals.Create your first agent, connect a provider, and send a message.

Check failure on line 175 in content/docs/agents/get-started/core-concepts.mdx

View workflow job for this annotation

GitHub Actions / vale

[vale] content/docs/agents/get-started/core-concepts.mdx#L175

[Google.Spacing] 's.C' should have one space.
Raw output
{"message": "[Google.Spacing] 's.C' should have one space.", "location": {"path": "content/docs/agents/get-started/core-concepts.mdx", "range": {"start": {"line": 175, "column": 79}}}, "severity": "ERROR"}
</Card>
<Card
icon={<HomeIcon />}
href="/agents/agent-logic/overview"
title="Agent logic"
>
Connect your preferred framework or runtime.
</Card>
</Cards>
3 changes: 3 additions & 0 deletions content/docs/agents/get-started/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pages": ["what-is-aci", "core-concepts", "quickstart"]
}
6 changes: 6 additions & 0 deletions content/docs/agents/get-started/quickstart.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: "Quickstart"
pageTitle: 'Novu Agents Quickstart'
description: 'Get started with Novu Agents'
icon: Zap
---
Loading
Loading