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 000000000..1e845df6c
--- /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 (<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 (>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 40f105158..239160163 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 9d85ca2c0..000000000
--- 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 (
-
- ...
--
- ...
-
- );
- };
-```
-
-#### 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 (
-
- ...
-
- ...
-
- );
-};
-
-const Text: FC = ({ children }) => {
- return (
-
-
- {children}
-
- ...
-
- );
-};
-```
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 6d4e9a5d2..000000000
--- 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 79c511230..000000000
--- 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 000000000..35f7dec62
--- /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";
+
+
+ This migration guide is for the upcoming v0.6 release.
+
+
+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).