From 6ffbfce553159e54aee61e8cf59f94a497f46778 Mon Sep 17 00:00:00 2001
From: Simon Farshid <simon.farshid@outlook.com>
Date: Wed, 9 Oct 2024 21:25:37 -0700
Subject: [PATCH] docs: add v0.6 migration guide (#960)

---
 .../docs/migrations/deprecation-policy.mdx    |  41 +++++
 apps/docs/content/docs/migrations/meta.json   |   2 +-
 apps/docs/content/docs/migrations/v0-3.mdx    |  50 ------
 apps/docs/content/docs/migrations/v0-4.mdx    |  40 -----
 apps/docs/content/docs/migrations/v0-5.mdx    |  18 --
 apps/docs/content/docs/migrations/v0-6.mdx    | 163 ++++++++++++++++++
 6 files changed, 205 insertions(+), 109 deletions(-)
 create mode 100644 apps/docs/content/docs/migrations/deprecation-policy.mdx
 delete mode 100644 apps/docs/content/docs/migrations/v0-3.mdx
 delete mode 100644 apps/docs/content/docs/migrations/v0-4.mdx
 delete mode 100644 apps/docs/content/docs/migrations/v0-5.mdx
 create mode 100644 apps/docs/content/docs/migrations/v0-6.mdx

diff --git a/apps/docs/content/docs/migrations/deprecation-policy.mdx b/apps/docs/content/docs/migrations/deprecation-policy.mdx
new file mode 100644
index 0000000000..1e845df6c9
--- /dev/null
+++ b/apps/docs/content/docs/migrations/deprecation-policy.mdx
@@ -0,0 +1,41 @@
+---
+title: Deprecation Policy
+---
+
+assistant-ui is committed to providing a stable API, so you can spend your time building amazing things on top of it.
+
+Rarely, we need to deprecate a feature we've already shipped, because it is causing performance, usability, or security issues.
+In such cases, we will communicate the intent to unship as soon as possible by marking the feature as `@deprecated` and publishing a notice in the documentation.
+
+Deprecations and breaking changes primarily affect new features released. The longer an API has been in the library, the less likely it is to be deprecated.
+For features that have long existed in the library, we will provider a longer deprecation notice period (as described below).
+
+Below is a list of features considered stable and those considered experimental.
+
+## Experimental Features
+
+These features may be removed at any time without notice.
+
+- Anything marked as `unstable_`, `experimental_`, or `internal`
+- The `RuntimeCore` API (conisdered internal)
+
+## Beta Features
+
+A deprecation of this features will undergo a short (&lt;1) month deprecation notice period.
+
+- TailwindCSS Plugins (e.g. `@assistant-ui/react/tailwindcss`)
+- Context API
+- Runtime API
+- Message types
+- Styled UI components
+- Primitive Hooks (e.g. useBranchPickerNext)
+- Attachment APIs
+- shadcn-ui styles
+
+## Stable Features
+
+A deprecation of this features will undergo a long (&gt;3 month) deprecation notice period.
+
+The following features are considered stable:
+
+- Primitives (except for `AttachmentPrimitive`)
diff --git a/apps/docs/content/docs/migrations/meta.json b/apps/docs/content/docs/migrations/meta.json
index 40f1051584..2391601631 100644
--- a/apps/docs/content/docs/migrations/meta.json
+++ b/apps/docs/content/docs/migrations/meta.json
@@ -1,4 +1,4 @@
 {
   "title": "Migrations",
-  "pages": ["v0-5", "v0-4", "v0-3"]
+  "pages": ["deprecation-policy", "v0-6"]
 }
diff --git a/apps/docs/content/docs/migrations/v0-3.mdx b/apps/docs/content/docs/migrations/v0-3.mdx
deleted file mode 100644
index 9d85ca2c0a..0000000000
--- a/apps/docs/content/docs/migrations/v0-3.mdx
+++ /dev/null
@@ -1,50 +0,0 @@
----
-title: Migration to v0.3
----
-
-## Changes to the `Thread.tsx` template
-
-### Removal of `MessagePrimitive.InProgress`
-
-Remove `MessagePrimitive.InProgress` from `Thread.tsx`.
-
-```diff
-  const AssistantMessage = () => {
-    return (
-      <MessagePrimitive.Root>
-        ...
--       <MessagePrimitive.InProgress className="..." />
-        ...
-      </MessagePrimitive.Root>
-    );
-  };
-```
-
-#### Custom loading indicator
-
-In case you want a custom loading indicator (other than the dot), create a custom Text component and pass it to the `MessagePrimitive.Content` component.
-
-```tsx {1,7,13-22}
-import { ContentPartPrimitive } from "@assistant-ui/react";
-
-const AssistantMessage = () => {
-  return (
-    <MessagePrimitive.Root>
-      ...
-      <MessagePrimitive.Content components={{ Text }} />
-      ...
-    </MessagePrimitive.Root>
-  );
-};
-
-const Text: FC = ({ children }) => {
-  return (
-    <ContentPartPrimitive.InProgress>
-      <ContentPartPrimitive.Text className="whitespace-pre-line">
-        {children}
-      </ContentPartPrimitive.Text>
-      <ContentPartPrimitive.InProgress>...</ContentPartPrimitive.InProgress>
-    </ContentPartPrimitive.InProgress>
-  );
-};
-```
diff --git a/apps/docs/content/docs/migrations/v0-4.mdx b/apps/docs/content/docs/migrations/v0-4.mdx
deleted file mode 100644
index 6d4e9a5d21..0000000000
--- a/apps/docs/content/docs/migrations/v0-4.mdx
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: Migration to v0.4
----
-
-## ThreadAssistantMessage / ThreadUserMessage
-
-The type `AssistantMessage` has been renamed to `ThreadAssistantMessage`.
-
-```diff
-- import { AssistantMessage } from "@assistant-ui/react";
-+ import { ThreadAssistantMessage } from "@assistant-ui/react";
-```
-
-The type `UserMessage` has been renamed to `ThreadUserMessage`.
-
-```diff
-- import { UserMessage } from "@assistant-ui/react";
-+ import { ThreadUserMessage } from "@assistant-ui/react";
-```
-
-The type `AssistantContentPart` has been renamed to `ThreadAssistantContentPart`.
-
-```diff
-- import { AssistantContentPart } from "@assistant-ui/react";
-+ import { ThreadAssistantContentPart } from "@assistant-ui/react";
-```
-
-The type `UserContentPart` has been renamed to `ThreadUserContentPart`.
-
-```diff
-- import { UserContentPart } from "@assistant-ui/react";
-+ import { ThreadUserContentPart } from "@assistant-ui/react";
-```
-
-## `@assistant-ui/react-ui` is now `@assistant-ui/react`
-
-```diff
-- import { Thread } from "@assistant-ui/react-ui";
-+ import { Thread } from "@assistant-ui/react";
-```
diff --git a/apps/docs/content/docs/migrations/v0-5.mdx b/apps/docs/content/docs/migrations/v0-5.mdx
deleted file mode 100644
index 79c5112304..0000000000
--- a/apps/docs/content/docs/migrations/v0-5.mdx
+++ /dev/null
@@ -1,18 +0,0 @@
----
-title: Migration to v0.5
----
-
-## Assistant Message Status / Content Part Status
-
-The previous `AssistantMessage.status` field has been reworked:
-
-- `in_progress` is now `{ type: "running" }`
-- `error` is now `{ type: "incomplete", reason: "error", error: unknown }`
-
-The previous value `done` now maps to one of the following values:
-
-- `{ type: "requires-action", reason: "tool-calls" }`
-- `{ type: "complete", reason: "stop" | "unknown" }`
-- `{ type: "incomplete", reason: "cancelled" | "tool-calls" | "length" | "content-filter" | "other" }`
-
-The same applies to `ContentPart` status fields.
diff --git a/apps/docs/content/docs/migrations/v0-6.mdx b/apps/docs/content/docs/migrations/v0-6.mdx
new file mode 100644
index 0000000000..35f7dec620
--- /dev/null
+++ b/apps/docs/content/docs/migrations/v0-6.mdx
@@ -0,0 +1,163 @@
+---
+title: Migration to v0.6
+---
+
+import { Callout } from "fumadocs-ui/components/callout";
+
+<Callout type="info">
+  This migration guide is for the upcoming v0.6 release.
+</Callout>
+
+This guide serves as a reference for users facing breaking changes during upgrade to v0.6. You do not need to read this guide to upgrade to v0.6.
+
+All breaking changes in v0.6 are renames or removals of existing APIs. Therefore, all breaking changes should cause a Typescript error, so you can simply check for errors after upgrading.
+
+# Context API simplifications
+
+## `useThreadContext`, `useMessageContext`, ... replaced with direct imports of stores
+
+`useAssistantContext`, `useThreadContext`, `useMessageContext` and `useContentPartContext` have been removed in favor of direct exports from `@assistant-ui/react`;
+
+```diff
+-const { useThread } = useThreadContext();
+
++import { useThread } from "@assistant-ui/react";
+```
+
+# Assistant Context API simplifications
+
+## `useAssistantActions` replaced with `useAssistantRuntime`
+
+`useAssistantActions` has been removed in favor of `useAssistantRuntime`.
+
+```diff
+-const switchToNewThread = useAssistantActions(a => a.switchToNewThread);
++const runtime = useAssistantRuntime();
++runtime.switchToNewThread();
+```
+
+## `switchToThread(null)` replaced with `switchToNewThread()`
+
+```diff
+-useThreadRuntime().switchToThread(null);
++useThreadRuntime().switchToNewThread();
+```
+
+## `runtime.subscribe` removed, `subscribeToMainThread` removed
+
+Previously, you needed to subscribe to the runtime to receive updates whenever the main thread changed and resubscribe to the main thread whenever you switched to a new thread. The `runtime.thread` value now always refers to the current main thread, there is no need to subscribe to the runtime anymore.
+
+# ThreadRuntime API simplifications
+
+## `useThreadActions` replaced with `useThreadRuntime`
+
+`useThreadActions` has been removed in favor of `useThreadRuntime`.
+
+```diff
+-const reload = useThreadActions(a => a.reload);
++const threadRuntime = useThreadRuntime();
++threadRuntime.reload();
+```
+
+## State values moved to `threadRuntime.getState()`
+
+In order to make it clear that accessing the state only provides a snapshot of the current state and will not cause a re-render on changes, the state values of `useThreadRutnime` have been moved to `threadRuntime.getState()`.
+
+```diff
+-const isRunning = useThreadRuntime().isRunning; // anti-pattern, your code will not update on change
++const isRunning = useThread(t => t.isRunning);
+```
+
+## `useThreadStore` replaced with `useThreadRuntime().getState()`
+
+`useThreadStore` has been removed in favor of `useThreadRuntime().getState()`.
+
+## `threadRuntime.getBranches()` replaced with `useThreadRuntime().getMessageByIndex(idx).getState().branchNumber/Count`
+
+The branch IDs are an internal implementation detail. The new Message Runtime API provides `branchNumber` and `branchCount` state fields that can be used instead.
+
+## New Message Runtime API replaces several methods from `useThreadRuntime`
+
+A few methods from `useThreadRuntime` have been moved to `useMessageRuntime()`.
+
+- `threadRuntime.switchToBranch()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).switchToBranch()`.
+- `threadRuntime.addToolResult()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).getContentPartByToolCallId(toolCallId).addToolResult()`.
+- `threadRuntime.speak()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).speak()`.
+- `threadRuntime.submitFeedback()` has been removed in favor of `useThreadRuntime().getMessageByIndex(idx).submitFeedback()`.
+- `threadRuntime.getEditComposer()` has been removed in favor of `useThreadRuntime().getMesssageById(id).getMessageByIndex(idx).composer`.
+- `threadRuntime.beginEdit()` has been removed in favor of `useThreadRuntime().getMesssageById(id).getMessageByIndex(idx).composer.beginEdit()`.
+
+# Composer Runtime API simplifications
+
+## Methods inside `useComposer` moved to `useComposerRuntime`
+
+`useComposer()` used to provide several methods such as `setText`, `addAttachment`, `send`, `edit`, `cancel`, ...
+These methods have been moved to `useComposerRuntime()`.
+
+## `useComposerStore` replaced with `useComposerRuntime().getState()`
+
+`useComposerStore` has been removed in favor of `useComposerRuntime().getState()`.
+
+## `value` `setValue` replaced with `text` `setText`
+
+```diff
+-useComposer(c => c.value);
++useComposer(c => c.text);
+```
+
+## `reset`, `focus`, `onFocus` methods removed
+
+These methods have been removed.
+
+# Message Context API simplifications
+
+## Flattened context values `useMessage().message` -> `useMessage()`
+
+`MessageState` is now itself a message, so you no longer need to access the nested `useMessage().message` field.
+
+```diff
+-useMessage(m => m.message.content);
++useMessage(m => m.content);
+```
+
+## `useMessageStore` replaced with `useMessageRuntime().getState()`
+
+`useMessageStore` has been removed in favor of `useMessageRuntime().getState()`.
+
+# Content Part Context API simplifications
+
+## Flattened context values `useContentPart().part` -> `useContentPart()`
+
+`ContentPartState` is now itself a content part, so you no longer need to access the nested `useContentPart().part` field.
+
+```diff
+-useContentPart(c => c.part.type);
++useContentPart(c => c.type);
+```
+
+This also applies to tool UI render functions:
+
+```diff
+ makeAssistantToolUI({
+   ...
+-  render: ({ part: { args } }) => <>{args}</>,
++  render: ({ args }) => <>{args}</>,
+ });
+```
+
+# Attachment Context API simplifications
+
+## Flattened context values `useAttachment().attachment` -> `useAttachment()`
+
+`AttachmentState` is now itself an attachment, so you no longer need to access the nested `useAttachment().attachment` field.
+
+```diff
+-useAttachment(a => a.attachment.type);
++useAttachment(a => a.type);
+```
+
+# Roundtrips rename to steps
+
+`AssistantMessage.roundtrips` was renamed to `AssistantMessage.metadata.steps`.
+
+Edge runtime's `maxToolRoundtrips` was replaced with `maxSteps` (which is `maxToolRoundtrips` + 1; if you had `maxToolRoundtrips` at 2, set `maxSteps` to 3).