Skip to content
Open
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
31 changes: 17 additions & 14 deletions api-reference/sdk/models/data-models.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2785,11 +2785,11 @@ Props for VeltCommentDialogReplyAvatarsListItem.

Inherits all properties from [`CommentDialogCommonProps`](#commentdialogcommonprops).

#### CommentDialogAgentSuggestionProps
#### CommentDialogSuggestionProps

## [Usage Examples →](/ui-customization/features/async/comments/comment-dialog/primitives#veltcommentdialogagentsuggestion)
## [Usage Examples →](/ui-customization/features/async/comments/comment-dialog/primitives#veltcommentdialogsuggestion)

Props for VeltCommentDialogAgentSuggestion and its sub-components.
Props for VeltCommentDialogSuggestion and its sub-components.

Inherits all properties from [`CommentDialogCommonProps`](#commentdialogcommonprops).

Expand Down Expand Up @@ -8632,19 +8632,21 @@ Optional config passed to [`enableSuggestionMode()`](/api-reference/sdk/api/api-
| ------------------- | ------------------------------------------------------------- | -------- | -------------------------------------------------------- |
| `onTargetEditStart` | [`TargetEditStartHandler<T>`](#targeteditstarthandlert) | No | Called when user begins editing a suggestion target |
| `onTargetEditCommit`| [`TargetEditCommitHandler<T>`](#targeteditcommithandlert) | No | Called when an edit is committed as a suggestion |
| `autoCommit` | `boolean` | No | When `true` (default) and no `onTargetEditCommit` handler is provided, every detected edit auto-commits as a suggestion using the SDK's default summary. Pass `false` for detect-only mode — the `targetEditCommit` event still fires, but nothing commits until a subscriber calls the event payload's `commitSuggestion` builder. Ignored when `onTargetEditCommit` is provided. |

#### CommitSuggestionConfig\<T\>

---

Passed to [`commitSuggestion()`](/api-reference/sdk/api/api-methods#commitsuggestion).

| Property | Type | Required | Description |
| ---------- | ------------------------- | -------- | --------------------------------------------- |
| `targetId` | `string` | Yes | ID of the target being committed |
| `newValue` | `T` | Yes | Proposed value to store in the suggestion |
| `summary` | `string` | No | Human-readable description of the change |
| `metadata` | `Record<string, unknown>` | No | Arbitrary caller-supplied metadata |
| Property | Type | Required | Description |
| ------------- | ------------------------- | -------- | --------------------------------------------- |
| `targetId` | `string` | Yes | ID of the target being committed |
| `newValue` | `T` | Yes | Proposed value to store in the suggestion |
| `summary` | `string` | No | Human-readable description of the change. Becomes the seeded comment's plain text. |
| `summaryHtml` | `string` | No | Optional HTML body for the seeded suggestion comment (for example, a color-coded diff). Sanitized with DOMPurify at render time — inline `style` is preserved; script and event-handler content is stripped. |
| `metadata` | `Record<string, unknown>` | No | Arbitrary caller-supplied metadata |

### Handler Types

Expand Down Expand Up @@ -8685,12 +8687,13 @@ type TargetEditStartResult = void;

---

Optional return from [`TargetEditCommitHandler`](#targeteditcommithandlert) to override `summary` or `metadata` on commit.
Optional return from [`TargetEditCommitHandler`](#targeteditcommithandlert) to override `summary`, `summaryHtml`, or `metadata` on commit.

| Property | Type | Required | Description |
| ---------- | ------------------------- | -------- | ---------------------------------------- |
| `summary` | `string` | No | Override for the suggestion summary |
| `metadata` | `Record<string, unknown>` | No | Override for the suggestion metadata |
| Property | Type | Required | Description |
| ------------- | ------------------------- | -------- | ---------------------------------------- |
| `summary` | `string` | No | Override for the suggestion summary |
| `summaryHtml` | `string` | No | Optional HTML body for the seeded suggestion comment. Sanitized with DOMPurify at render time. |
| `metadata` | `Record<string, unknown>` | No | Override for the suggestion metadata |

#### TargetEditStartHandler\<T\>

Expand Down
78 changes: 72 additions & 6 deletions async-collaboration/suggestions/overview.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Suggestions (Beta)"
sidebarTitle: "Suggestions"
description: "Capture edits from humans or AI agents as reviewable suggestions with accept and reject actions on the comment dialog."
description: "Capture edits from humans or AI agents as reviewable suggestions in Velt, with diff-style accept and reject actions on the comment dialog."
---

## Overview
Expand Down Expand Up @@ -188,11 +188,43 @@ suggestionElement.isSuggestionModeEnabled$().subscribe((isEnabled) => {

#### 3. Capture Edits as Suggestions

When a user finishes an edit, you decide how it becomes a suggestion. There are three ways, from simplest to most control. Use one per target; only one of them handles any given edit.
When a user finishes an edit, you decide how it becomes a suggestion. There are four ways, from simplest to most control. Use one per target; only one of them handles any given edit.

**Option 1: Auto-commit with `onTargetEditCommit` (simplest)**
**Option 1: Zero-config auto-commit (default)**

Pass `onTargetEditCommit` when you enable suggestion mode. The SDK calls it with the old and new values every time a user finishes an edit. Return an object and the SDK creates the suggestion right away, using your `summary` and `metadata`. This is the path most apps want. (`onTargetEditStart` fires when editing begins; it's informational in v1 and its return value is reserved for future use.)
The simplest setup: enable suggestion mode with no handler at all. Every detected edit on a tagged target is committed automatically, using the SDK's default diff summary. This is controlled by the new `autoCommit` flag on [`EnableSuggestionModeConfig`](/api-reference/sdk/models/data-models#enablesuggestionmodeconfig), which **defaults to `true`**. Pass `autoCommit: false` for detect-only mode — the `targetEditCommit` event still fires, but nothing is created until you call the event's `commitSuggestion` builder (see Option 3).

<Tabs>
<Tab title="React / Next.js">
```jsx
const { enableSuggestionMode } = useEnableSuggestionMode();

// Zero-config: edits on tagged targets auto-commit as suggestions.
enableSuggestionMode();

// Detect-only: events fire, but nothing commits until you call the builder.
enableSuggestionMode({ autoCommit: false });
```
</Tab>

<Tab title="Other Frameworks">
```js
// Zero-config: edits on tagged targets auto-commit as suggestions.
suggestionElement.enableSuggestionMode();

// Detect-only: events fire, but nothing commits until you call the builder.
suggestionElement.enableSuggestionMode({ autoCommit: false });
```
</Tab>
</Tabs>

<Note>
`autoCommit` is ignored when you pass `onTargetEditCommit` (Option 2) — the handler always wins, including its `null`-return deferral contract. The flag is cleared by `disableSuggestionMode()`; re-enabling without it resets to the default.
</Note>

**Option 2: Auto-commit with `onTargetEditCommit`**

Pass `onTargetEditCommit` when you enable suggestion mode. The SDK calls it with the old and new values every time a user finishes an edit. Return an object and the SDK creates the suggestion right away, using your `summary`, `summaryHtml`, and `metadata`. Use this when you want per-edit control over the suggestion body without falling all the way back to the event stream. (`onTargetEditStart` fires when editing begins; it's informational in v1 and its return value is reserved for future use.)

<Tabs>
<Tab title="React / Next.js">
Expand Down Expand Up @@ -232,7 +264,7 @@ suggestionElement.enableSuggestionMode({
Don't want every edit to become a suggestion automatically? Return `null` (or leave out `onTargetEditCommit`) and handle the edit yourself with the `targetEditCommit` event below, for example to validate the value or ask the user to confirm first.
</Tip>

**Option 2: Decide per edit with the `targetEditCommit` event**
**Option 3: Decide per edit with the `targetEditCommit` event**

If you skip `onTargetEditCommit`, subscribe to the `targetEditCommit` event instead. The event gives you the edit details plus a `commitSuggestion` function that's already tied to that edit. Call it to create the suggestion (you can override `summary` / `metadata`), or don't call it to discard the edit. Nothing is created until you call it.

Expand Down Expand Up @@ -271,7 +303,7 @@ suggestionElement.on('targetEditCommit').subscribe(({ details, commitSuggestion
</Tab>
</Tabs>

**Option 3: Create suggestions manually with `startSuggestion` / `commitSuggestion`**
**Option 4: Create suggestions manually with `startSuggestion` / `commitSuggestion`**

When there's no input for the SDK to watch (a custom widget, a canvas element, or an "AI proposes a change" button), create the suggestion yourself. Call `startSuggestion(targetId)` to capture the current value as `oldValue`, then `commitSuggestion(config)` with the `newValue` to create it.

Expand Down Expand Up @@ -318,6 +350,40 @@ const { id } = await suggestionElement.commitSuggestion({
`commitSuggestion` only works while suggestion mode is on and the `targetId` is known to the SDK (tagged in the DOM or registered via `registerTarget`). It also creates nothing when `newValue` is identical to the captured `oldValue`.
</Note>

##### Rich HTML summaries with `summaryHtml`

The suggestion card renders a seeded first comment using the `summary` you provide. Pass an optional `summaryHtml` alongside `summary` (on either `commitSuggestion(config)` or the `onTargetEditCommit` / event-builder return value) to render a formatted body — for example, a color-coded before/after diff. `summaryHtml` becomes the comment's `commentHtml`; plain `summary` (or the SDK's default diff text) stays in `commentText` as the fallback.

If you provide neither, the SDK renders a default styled HTML diff (old value in red italic, new value in green italic).

<Tabs>
<Tab title="React / Next.js">
```jsx
await commitSuggestion({
targetId: 'price-field',
newValue: 6000,
summary: 'Price: $5,000 → $6,000',
summaryHtml: '<p>Price: <s>$5,000</s> <b>$6,000</b></p>',
});
```
</Tab>

<Tab title="Other Frameworks">
```js
await suggestionElement.commitSuggestion({
targetId: 'price-field',
newValue: 6000,
summary: 'Price: $5,000 -> $6,000',
summaryHtml: '<p>Price: <s>$5,000</s> <b>$6,000</b></p>',
});
```
</Tab>
</Tabs>

<Note>
`summaryHtml` is sanitized with DOMPurify at render time — `<script>` tags and event-handler attributes are stripped. Inline `style` attributes are preserved, so rich diff styling survives.
</Note>

#### 4. Apply Accepted Suggestions

This is the step you can't skip. When a reviewer clicks **Accept** or **Reject** on the comment dialog, the SDK updates the suggestion's status but **does not change your data**. Listen for the `suggestionAccepted` event on the **comment element** (not the SuggestionElement), read `commentAnnotation.suggestion.newValue`, and write it to your state or backend yourself.
Expand Down
30 changes: 30 additions & 0 deletions release-notes/version-6/sdk-changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@ description: Release Notes of changes added to the core Velt SDK
- `@veltdev/sdk`
- `@veltdev/types`

<Update label="6.0.0-beta.13" description="July 20, 2026">

### New Features

- [**Suggestions**]: `enableSuggestionMode()` now auto-commits by default. A bare call turns edits on tagged targets into suggestion comments with zero additional configuration, using the SDK's default diff summary. Pass `autoCommit: false` for detect-only mode. Handler-based integrations (with `onTargetEditCommit`) are unaffected. [Learn more →](/async-collaboration/suggestions/overview#3-capture-edits-as-suggestions)

- [**Suggestions**]: New optional `summaryHtml` field on [`commitSuggestion(config)`](/api-reference/sdk/models/data-models#commitsuggestionconfigt) and on the [`onTargetEditCommit`](/api-reference/sdk/models/data-models#targeteditcommitresult) return value renders a formatted HTML body (for example, a color-coded before/after diff) on the seeded suggestion comment. When both `summary` and `summaryHtml` are omitted, the SDK renders a default styled diff. `summaryHtml` is sanitized with DOMPurify at render time. [Learn more →](/async-collaboration/suggestions/overview#rich-html-summaries-with-summaryhtml)

- [**Suggestions**]: The suggestion card now renders for **any** annotation with `type: 'suggestion'` (or `commentType: 'suggestion'`), not only agent-generated ones. Human-authored suggestion comments get the same header, diff body, and accept/reject actions as agent suggestions.

### Bug Fixes

- [**Comments**]: Fixed a class of stale-state bugs in the Comment Dialog's virtual-scroll row recycling. Drafts, edits, replies, assignee/mention state, and `velt-class` conditions now stay correctly bound to their own annotation through collapse/expand, group toggles, and cross-group scroll — in both the standard dialog and customer wireframes.

- [**Suggestions**]: A failed auto-commit no longer blocks retry — the `targetEditCommit` event's pre-bound `commitSuggestion` builder can now be called to recover.

- [**Comments**]: The reply composer now closes on deselect and no longer persists onto the wrong annotation after virtual-scroll recycling.

### Breaking Changes

<Warning>
These renames affect only integrations that use the low-level Comment Dialog **suggestion** wireframe or primitive components directly (React `VeltCommentDialog…` sub-components or the HTML `velt-comment-dialog-…` custom elements). Integrations using the default (non-wireframe) comment dialog are unaffected. The renames are hard — there are no runtime aliases for the old names.
</Warning>

- [**Comments**]: The suggestion card component tree was renamed from `AgentSuggestion` to `Suggestion` across React exports, wireframe dot-notation, HTML custom-element tags (including `-wireframe` variants), and `velt-suggestion*` CSS class prefixes. Every `VeltCommentDialogAgentSuggestion*` becomes `VeltCommentDialogSuggestion*`; every `velt-comment-dialog-agent-suggestion-*` tag becomes `velt-comment-dialog-suggestion-*`. Update every import, wireframe reference, custom-element tag, and any CSS override targeting the old class names. [Learn more →](/ui-customization/features/async/comments/comment-dialog/primitives)

- [**Comments**]: The old standalone accept/reject action row was renamed from `SuggestionAction` to `LegacySuggestionAction` and is now deprecated. It is superseded by the new `Suggestion` card inside the standard dialog and is retained only for standalone custom-element usage. Rename every `VeltCommentDialogSuggestionAction*` → `VeltCommentDialogLegacySuggestionAction*` and every `velt-comment-dialog-suggestion-action-*` → `velt-comment-dialog-legacy-suggestion-action-*`.

</Update>

<Update label="6.0.0-beta.10" description="July 14, 2026">

### New Features
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Comment Dialog — Structure"
description: "Canonical structure for the Velt Comment Dialog Wireframe (React & HTML mirrors). Order follows your provided JSX/HTML. Parent/child is defined only by the extension path. Direct children are marked with (Leaf) when they have no descendants."
description: "Canonical structure of the Velt Comment Dialog Wireframe for React and HTML — parent, child, and leaf components in the order they nest inside the dialog."
---

> **Conventions**
Expand Down Expand Up @@ -312,9 +312,9 @@ description: "Canonical structure for the Velt Comment Dialog Wireframe (React &

---

### `VeltCommentDialogWireframe.SuggestionAction`
- `VeltCommentDialogWireframe.SuggestionAction.Accept` **(Leaf)**
- `VeltCommentDialogWireframe.SuggestionAction.Reject` **(Leaf)**
### `VeltCommentDialogWireframe.LegacySuggestionAction`
- `VeltCommentDialogWireframe.LegacySuggestionAction.Accept` **(Leaf)**
- `VeltCommentDialogWireframe.LegacySuggestionAction.Reject` **(Leaf)**

---

Expand Down Expand Up @@ -619,6 +619,6 @@ description: "Canonical structure for the Velt Comment Dialog Wireframe (React &

---

### `velt-comment-dialog-suggestion-action-wireframe`
- `velt-comment-dialog-suggestion-action-accept-wireframe` **(Leaf)**
- `velt-comment-dialog-suggestion-action-reject-wireframe` **(Leaf)**
### `velt-comment-dialog-legacy-suggestion-action-wireframe`
- `velt-comment-dialog-legacy-suggestion-action-accept-wireframe` **(Leaf)**
- `velt-comment-dialog-legacy-suggestion-action-reject-wireframe` **(Leaf)**
Loading