Skip to content
Merged
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
2 changes: 2 additions & 0 deletions modules/ROOT/examples/live-demos/revisionhistory/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const revisions = [
name: 'James Wilson',
avatar: 'https://sneak-preview.tiny.cloud/demouserdirectory/images/employee_james-wilson_128_52f19412.jpg',
},
metadata: { source: 'ai' },
content: `
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Tiny Logo" src="https://www.tiny.cloud/docs/tinymce/latest/_images/logos/android-chrome-256x256.png" alt="TinyMCE Logo" width="128" height="128"></p>
<h2 style="text-align: center;">Welcome to the TinyMCE editor demo!</h2>
Expand Down Expand Up @@ -150,6 +151,7 @@ tinymce.init({
revisionhistory_fetch,
revisionhistory_fetch_revision,
revisionhistory_display_author: true,
revisionhistory_ai_attribution: true,
user_id: 'kai-nakamura',
fetch_users: (userIds) => Promise.all(userIds
.map((userId) =>
Expand Down
17 changes: 17 additions & 0 deletions modules/ROOT/pages/8.7.0-release-notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ The following premium plugin updates were released alongside {productname} {rele

// For information on the **<Premium plugin name 1>** plugin, see: xref:<plugincode>.adoc[<Premium plugin name 1>].

=== Revision History

The {productname} {release-version} release includes an accompanying release of the **Revision History** premium plugin.

**Revision History** includes the following additions.

==== Revisions can be attributed to AI and display an AI badge
// #TINY-14305
// #TINY-14306
// #TINY-14480

Revisions now support an optional `+metadata+` property. Setting its `+source+` field to `+'ai'+` marks a revision as AI-assisted, allowing integrators to track content produced by the xref:tinymceai.adoc[{productname} AI] plugin. When the new xref:revisionhistory.adoc#revisionhistory_ai_attribution[`+revisionhistory_ai_attribution+`] option is enabled, an AI badge is rendered on the cards of AI-assisted revisions.

For details on attributing revisions to AI, see xref:revisionhistory.adoc#attributing-ai-assisted-revisions[Attributing AI-assisted revisions].

For information on the **Revision History** plugin, see: xref:revisionhistory.adoc[Revision History].

=== Suggested Edits

The {productname} {release-version} release includes an accompanying release of the **Suggested Edits** premium plugin.
Expand Down
69 changes: 69 additions & 0 deletions modules/ROOT/pages/revisionhistory.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ The revision is an `+Object+` that contains the following fields:
| `+createdAt+` | `+string+` | required | A UTC datetime string in ISO-8061 format.
| `+content+` | `+string+` | optional | HTML string of the revision content. Empty string is considered as valid content.
| `+author+` | xref:#author[Author] `+Object+` | optional | The author of the revision.
| `+metadata+` | xref:#metadata[Metadata] `+Object+` | optional | Additional information about the revision, such as whether it was AI-assisted.
|===

=== Author
Expand All @@ -101,6 +102,72 @@ The author is an `+Object+` that represents the author or creator of a revision.
| `+avatar+` | `+string+` | optional | The URL of the author's avatar image. If not provided or invalid, the {pluginname} will use a generated avatar using the author's initials.
|===

=== Metadata

The metadata is an `+Object+` that holds additional information about a revision. It contains the following fields:

[cols="1,1,1,3",options="header"]
|===
| Field | Type | Required? | Description
| `+source+` | `+string+` | optional | The origin of the revision's content. A value of `+'ai'+` marks the revision as AI-assisted and, when xref:revisionhistory_ai_attribution[`+revisionhistory_ai_attribution+`] is enabled, displays an AI badge on the revision card.
|===

== Attributing AI-assisted revisions

A revision is identified as AI-assisted through the `+source+` field of its xref:#metadata[`+metadata+`] object. When `+metadata.source+` is `+'ai'+` and the xref:revisionhistory_ai_attribution[`+revisionhistory_ai_attribution+`] option is enabled, an AI badge appears on that revision card.

The {pluginname} plugin does not set this marker automatically. The xref:tinymceai.adoc[{productname} AI] plugin sets `+ai+` to `+true+` on the `+SetContent+` event for any content it inserts. Detecting that signal and recording it as `+metadata.source+` when saving a revision is the responsibility of the application. There are three steps to keep attribution accurate:

. **Detect**: Listen for the `+SetContent+` event and record when its `+ai+` property is `+true+`.
. **Save**: When saving a revision, set `+metadata.source+` to `+'ai'+` if AI contributed since the last save.
. **Restore**: When a revision is restored, carry its marker forward so later revisions remain correctly attributed.

[NOTE]
The AI badge appears only on `+saved+` revisions. The `+draft+` and `+initial+` revisions are generated from the editor's current content and do not carry `+metadata+`, so they never display the badge, even when that content was AI-assisted. See xref:#understanding-revision-types[Understanding revision types].

=== Saving an AI-assisted revision

The application is responsible for saving revisions and returns them through the xref:revisionhistory_fetch[`+revisionhistory_fetch+`] option. The following example tracks AI involvement from the `+SetContent+` event and attaches the `+metadata+` marker when saving a snapshot:

[source,js]
----
let aiAssisted = false;

// The TinyMCE AI plugin sets `ai: true` on the SetContent event for content it inserts.
editor.on('SetContent', (e) => {
if (e.ai) {
aiAssisted = true;
}
});

// Call this when saving a snapshot of the current content as a revision.
const saveRevision = () => {
const revision = {
revisionId: createRevisionId(), // Replace with your ID generation
createdAt: new Date().toISOString(),
content: editor.getContent(),
// Mark the revision as AI-assisted if AI contributed since the last save.
...(aiAssisted ? { metadata: { source: 'ai' } } : {})
};

saveToStorage(revision); // Replace with your storage call
aiAssisted = false; // Reset state of AI assistance for new content
};
----

=== Restoring an AI-assisted revision

Restoring a revision sets its content back into the editor and fires the `+VersionRestored+` event. The restored content is not flagged as AI-assisted, so look up the restored revision and carry its marker forward to the next save:

[source,js]
----
editor.on('VersionRestored', (e) => {
const restored = getFromStorage(e.revisionId); // Replace with your storage lookup
// Preserve attribution so the next saved revision reflects the restored content.
aiAssisted = restored?.metadata?.source === 'ai';
});
----


== Options

Expand All @@ -120,6 +187,8 @@ include::partial$configuration/revisionhistory_author.adoc[leveloffset=+1]

include::partial$configuration/revisionhistory_display_author.adoc[leveloffset=+1]

include::partial$configuration/revisionhistory_ai_attribution.adoc[leveloffset=+1]

include::partial$configuration/revisionhistory_css_url.adoc[leveloffset=+1]

include::partial$configuration/revisionhistory_diff_classes.adoc[leveloffset=+1]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[[revisionhistory_ai_attribution]]
== `revisionhistory_ai_attribution`

This option controls the display of the AI badge on revision cards. When set to `+true+`, an AI badge appears on each revision whose xref:revisionhistory.adoc#metadata[`+metadata+`] has `+source+` set to `+'ai'+`. For details on attributing revisions to AI, see xref:revisionhistory.adoc#attributing-ai-assisted-revisions[Attributing AI-assisted revisions].

*Type:* `+Boolean+`

*Default value:* `+false+`

*Possible values:* `+true+`, `+false+`

=== Example: using `revisionhistory_ai_attribution`

[source,js]
----
tinymce.init({
selector: 'textarea', // Change this value according to your HTML
plugins: 'revisionhistory',
toolbar: 'revisionhistory',
revisionhistory_fetch: () => Promise.resolve([]),
revisionhistory_ai_attribution: true
});
----
Loading