(null);
-
- const handleModeChange = (nextMode: HarnessModeId) => {
- currentHarnessMode = nextMode;
- setMode(nextMode);
- };
-
- const handleSubmit = () => {
- const message = textContent.trim();
- if (!message || isRunning || isLoadingMessages) return;
-
- onSend(message);
- setTextContent("");
- };
-
- useLayoutEffect(() => {
- const input = inputRef.current;
- if (!input) return;
-
- input.style.height = "0px";
- input.style.height = `${Math.max(input.scrollHeight, 24)}px`;
- }, [textContent]);
-
- return (
- 0 || undefined}
- onClick={(event) => {
- if (!(event.target as HTMLElement).closest("button, a, [role='button']")) {
- inputRef.current?.focus();
- }
- }}
- >
-
-
- );
-}
+import { useMemo } from "react";
export default function Page() {
const themeMode = useTheme();
- const chatProps = useMemo(
- () =>
- createMastraHarnessChatProps({
- getModeId: getCurrentHarnessMode,
- }),
- [],
- );
+ const chatProps = useMemo(() => createMastraHarnessChatProps(), []);
return (
@@ -202,7 +19,6 @@ export default function Page() {
componentLibrary={openuiChatLibrary}
agentName="Mastra Harness + OpenUI"
theme={{ mode: themeMode }}
- composer={MastraModeComposer}
conversationStarters={{
variant: "short",
options: [
diff --git a/examples/harnesses/mastra-harness/src/lib/mastra-harness-chat.ts b/examples/harnesses/mastra-harness/src/lib/mastra-harness-chat.ts
index 8fa8c221a..6bf733707 100644
--- a/examples/harnesses/mastra-harness/src/lib/mastra-harness-chat.ts
+++ b/examples/harnesses/mastra-harness/src/lib/mastra-harness-chat.ts
@@ -6,12 +6,6 @@ import {
type ThreadStore,
} from "./thread-store";
-export type HarnessModeId = "assist" | "brief";
-
-interface ChatPropsOptions {
- getModeId?: () => HarnessModeId;
-}
-
function sseLinesToEvents(chunk: string): AGUIEvent[] {
return chunk
.split("\n")
@@ -72,7 +66,6 @@ async function persistAssistantFromStream(
}
export function createMastraHarnessChatProps(
- options: ChatPropsOptions = {},
storage: KVStorage = getClientStorage(),
store: ThreadStore = createThreadStore(storage),
) {
@@ -96,7 +89,7 @@ export function createMastraHarnessChatProps(
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ messages, modeId: options.getModeId?.(), threadId }),
+ body: JSON.stringify({ messages, threadId }),
signal: abortController.signal,
});
diff --git a/examples/harnesses/mastra-harness/src/lib/mastra-harness.ts b/examples/harnesses/mastra-harness/src/lib/mastra-harness.ts
index dacd1d8a3..68587841a 100644
--- a/examples/harnesses/mastra-harness/src/lib/mastra-harness.ts
+++ b/examples/harnesses/mastra-harness/src/lib/mastra-harness.ts
@@ -11,7 +11,7 @@ const systemPrompt = readFileSync(
"utf-8",
);
-const HARNESS_CONFIG_VERSION = "2026-06-24.3";
+const HARNESS_CONFIG_VERSION = "2026-07-04.1";
const getWeather = createTool({
id: "get_weather",
@@ -90,40 +90,19 @@ function createHarness() {
url: process.env.MASTRA_HARNESS_DB_URL || "file:./.mastra-harness/openui-harness.db",
}),
agent,
- defaultModeId: "assist",
+ defaultModeId: "default",
modes: [
{
- id: "assist",
- name: "Assist",
+ id: "default",
+ name: "Default",
description: "Use tools and render complete OpenUI responses.",
metadata: { default: true },
instructions:
[
- "You are in Assist mode.",
- "Make this mode visibly different from Brief mode.",
"Optimize for useful depth, exploration, and rich generated UI.",
"When the prompt asks for analysis, planning, comparison, status, or data, prefer structured UI such as SectionBlock, Table, TagBlock, ListBlock, charts, and FollowUpBlock.",
"Use tools when relevant and include the tool-derived facts in the rendered UI.",
"Default shape: root = Card([header, overview, details, actions, followups]) or a richer equivalent.",
- "Do not compress the answer into an executive-summary-only card unless the user explicitly asks for a brief.",
- ].join("\n"),
- },
- {
- id: "brief",
- name: "Brief",
- description: "Summarize the conversation into a tiny executive brief.",
- instructions:
- [
- "You are in Brief mode.",
- "Make this mode visibly different from Assist mode.",
- "Optimize for speed, scanability, and minimal UI.",
- "Produce a tiny executive brief, not a dashboard, report, or full analysis.",
- "Even if the user asks for a dashboard, table, chart, plan, or detailed comparison, Brief mode should summarize the answer as a brief.",
- "Use exactly two rendered child components inside root: a header and one body text component.",
- "Required shape: root = Card([header, brief]) where header is CardHeader(\"Brief\", \"...\") and brief is MarkDownRenderer(...) or TextContent(...).",
- "Keep prose under 90 words unless the user explicitly requests more.",
- "Use short bullets. Include only: key takeaway, blocker/risk if any, and next action.",
- "Never use charts, tables, forms, carousels, tabs, SectionBlock, FollowUpBlock, ListBlock, or extra rendered components in Brief mode.",
].join("\n"),
},
],
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 197638c88..7199b8bb6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -397,9 +397,6 @@ importers:
'@openuidev/react-ui':
specifier: workspace:*
version: link:../../../packages/react-ui
- lucide-react:
- specifier: ^0.562.0
- version: 0.562.0(react@19.2.3)
next:
specifier: 16.2.6
version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2)
From 062636b536a8b43bc8b1f88e7339ab6589010ac3 Mon Sep 17 00:00:00 2001
From: Visharad Kashyap <154831195+vishxrad@users.noreply.github.com>
Date: Sat, 4 Jul 2026 19:28:35 +0530
Subject: [PATCH 3/4] Update Mastra harness example copy
---
examples/harnesses/mastra-harness/README.md | 8 ++++----
examples/harnesses/mastra-harness/src/app/layout.tsx | 4 ++--
examples/harnesses/mastra-harness/src/app/page.tsx | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/examples/harnesses/mastra-harness/README.md b/examples/harnesses/mastra-harness/README.md
index 680f21dfa..18ec18f41 100644
--- a/examples/harnesses/mastra-harness/README.md
+++ b/examples/harnesses/mastra-harness/README.md
@@ -1,8 +1,8 @@
-# OpenUI + Mastra Harness
+# Mastra Harness Chat
-A generative-UI chat application backed by Mastra's new `Harness` API. The app keeps the normal
-OpenUI `` chat surface, while the backend runs a persistent Mastra Harness session
-with LibSQL-backed threads/state and tool activity streamed into OpenUI as AG-UI events.
+An OpenUI chat example backed by Mastra's new `Harness` API. The app keeps the normal
+OpenUI `` surface, while the backend runs a persistent Mastra Harness session with
+LibSQL-backed threads/state and tool activity streamed into OpenUI as AG-UI events.
## How it works
diff --git a/examples/harnesses/mastra-harness/src/app/layout.tsx b/examples/harnesses/mastra-harness/src/app/layout.tsx
index c53909782..e4b680e77 100644
--- a/examples/harnesses/mastra-harness/src/app/layout.tsx
+++ b/examples/harnesses/mastra-harness/src/app/layout.tsx
@@ -3,8 +3,8 @@ import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
- title: "Mastra Harness + OpenUI",
- description: "Generative UI chat powered by Mastra Harness",
+ title: "Mastra Harness Chat",
+ description: "Persistent OpenUI chat backed by Mastra Harness tools and AG-UI streaming",
};
export default function RootLayout({
diff --git a/examples/harnesses/mastra-harness/src/app/page.tsx b/examples/harnesses/mastra-harness/src/app/page.tsx
index ca36982fa..a05b374eb 100644
--- a/examples/harnesses/mastra-harness/src/app/page.tsx
+++ b/examples/harnesses/mastra-harness/src/app/page.tsx
@@ -17,7 +17,7 @@ export default function Page() {
{...chatProps}
streamProtocol={agUIAdapter()}
componentLibrary={openuiChatLibrary}
- agentName="Mastra Harness + OpenUI"
+ agentName="Mastra Harness Chat"
theme={{ mode: themeMode }}
conversationStarters={{
variant: "short",
From b72de637a903ef777205137f540b8cbb3dacb6d3 Mon Sep 17 00:00:00 2001
From: Visharad Kashyap <154831195+vishxrad@users.noreply.github.com>
Date: Sat, 4 Jul 2026 23:16:42 +0530
Subject: [PATCH 4/4] Rename Mastra harness example folder
---
.../{mastra-harness => mastra-harness-chat}/.env.example | 2 +-
.../{mastra-harness => mastra-harness-chat}/.gitignore | 0
.../{mastra-harness => mastra-harness-chat}/README.md | 4 ++--
.../{mastra-harness => mastra-harness-chat}/eslint.config.mjs | 0
.../{mastra-harness => mastra-harness-chat}/next.config.ts | 0
.../{mastra-harness => mastra-harness-chat}/package.json | 2 +-
.../postcss.config.mjs | 0
.../src/app/api/chat/route.ts | 0
.../src/app/globals.css | 0
.../src/app/layout.tsx | 0
.../{mastra-harness => mastra-harness-chat}/src/app/page.tsx | 0
.../src/generated/system-prompt.txt | 0
.../src/hooks/use-system-theme.tsx | 0
.../src/lib/harness-stream.ts | 0
.../src/lib/mastra-harness-chat.ts | 0
.../src/lib/mastra-harness.ts | 4 ++--
.../src/lib/thread-store.ts | 4 ++--
.../{mastra-harness => mastra-harness-chat}/src/library.ts | 0
.../{mastra-harness => mastra-harness-chat}/tsconfig.json | 0
pnpm-lock.yaml | 2 +-
20 files changed, 9 insertions(+), 9 deletions(-)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/.env.example (72%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/.gitignore (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/README.md (94%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/eslint.config.mjs (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/next.config.ts (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/package.json (96%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/postcss.config.mjs (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/app/api/chat/route.ts (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/app/globals.css (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/app/layout.tsx (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/app/page.tsx (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/generated/system-prompt.txt (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/hooks/use-system-theme.tsx (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/lib/harness-stream.ts (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/lib/mastra-harness-chat.ts (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/lib/mastra-harness.ts (98%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/lib/thread-store.ts (95%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/src/library.ts (100%)
rename examples/harnesses/{mastra-harness => mastra-harness-chat}/tsconfig.json (100%)
diff --git a/examples/harnesses/mastra-harness/.env.example b/examples/harnesses/mastra-harness-chat/.env.example
similarity index 72%
rename from examples/harnesses/mastra-harness/.env.example
rename to examples/harnesses/mastra-harness-chat/.env.example
index ed7ee6a4e..778c5b5e3 100644
--- a/examples/harnesses/mastra-harness/.env.example
+++ b/examples/harnesses/mastra-harness-chat/.env.example
@@ -3,4 +3,4 @@ OPENAI_API_KEY=sk-...
# OPENAI_BASE_URL=https://api.openai.com/v1
#
# Optional: persists Mastra Harness threads/state to a different LibSQL database.
-# MASTRA_HARNESS_DB_URL=file:./.mastra-harness/openui-harness.db
+# MASTRA_HARNESS_DB_URL=file:./.mastra-harness-chat/openui-harness.db
diff --git a/examples/harnesses/mastra-harness/.gitignore b/examples/harnesses/mastra-harness-chat/.gitignore
similarity index 100%
rename from examples/harnesses/mastra-harness/.gitignore
rename to examples/harnesses/mastra-harness-chat/.gitignore
diff --git a/examples/harnesses/mastra-harness/README.md b/examples/harnesses/mastra-harness-chat/README.md
similarity index 94%
rename from examples/harnesses/mastra-harness/README.md
rename to examples/harnesses/mastra-harness-chat/README.md
index 18ec18f41..eea5e34cb 100644
--- a/examples/harnesses/mastra-harness/README.md
+++ b/examples/harnesses/mastra-harness-chat/README.md
@@ -49,7 +49,7 @@ pnpm install
Create an env file in this example:
```bash
-cd examples/harnesses/mastra-harness
+cd examples/harnesses/mastra-harness-chat
cp .env.example .env.local
```
@@ -68,7 +68,7 @@ Open [http://localhost:3000](http://localhost:3000).
| `OPENAI_API_KEY` | unset | API key for the configured model |
| `OPENAI_MODEL` | `openai/gpt-5.5` | Mastra model id |
| `OPENAI_BASE_URL` | `https://api.openai.com/v1` | OpenAI-compatible endpoint |
-| `MASTRA_HARNESS_DB_URL` | `file:./.mastra-harness/openui-harness.db` | LibSQL database for Harness state |
+| `MASTRA_HARNESS_DB_URL` | `file:./.mastra-harness-chat/openui-harness.db` | LibSQL database for Harness state |
The `dev` and `build` scripts regenerate `src/generated/system-prompt.txt` from `src/library.ts`
before starting Next, so the backend prompt and frontend OpenUI renderer stay aligned.
diff --git a/examples/harnesses/mastra-harness/eslint.config.mjs b/examples/harnesses/mastra-harness-chat/eslint.config.mjs
similarity index 100%
rename from examples/harnesses/mastra-harness/eslint.config.mjs
rename to examples/harnesses/mastra-harness-chat/eslint.config.mjs
diff --git a/examples/harnesses/mastra-harness/next.config.ts b/examples/harnesses/mastra-harness-chat/next.config.ts
similarity index 100%
rename from examples/harnesses/mastra-harness/next.config.ts
rename to examples/harnesses/mastra-harness-chat/next.config.ts
diff --git a/examples/harnesses/mastra-harness/package.json b/examples/harnesses/mastra-harness-chat/package.json
similarity index 96%
rename from examples/harnesses/mastra-harness/package.json
rename to examples/harnesses/mastra-harness-chat/package.json
index c978c074a..04a995137 100644
--- a/examples/harnesses/mastra-harness/package.json
+++ b/examples/harnesses/mastra-harness-chat/package.json
@@ -1,5 +1,5 @@
{
- "name": "mastra-harness",
+ "name": "mastra-harness-chat",
"version": "0.1.0",
"private": true,
"scripts": {
diff --git a/examples/harnesses/mastra-harness/postcss.config.mjs b/examples/harnesses/mastra-harness-chat/postcss.config.mjs
similarity index 100%
rename from examples/harnesses/mastra-harness/postcss.config.mjs
rename to examples/harnesses/mastra-harness-chat/postcss.config.mjs
diff --git a/examples/harnesses/mastra-harness/src/app/api/chat/route.ts b/examples/harnesses/mastra-harness-chat/src/app/api/chat/route.ts
similarity index 100%
rename from examples/harnesses/mastra-harness/src/app/api/chat/route.ts
rename to examples/harnesses/mastra-harness-chat/src/app/api/chat/route.ts
diff --git a/examples/harnesses/mastra-harness/src/app/globals.css b/examples/harnesses/mastra-harness-chat/src/app/globals.css
similarity index 100%
rename from examples/harnesses/mastra-harness/src/app/globals.css
rename to examples/harnesses/mastra-harness-chat/src/app/globals.css
diff --git a/examples/harnesses/mastra-harness/src/app/layout.tsx b/examples/harnesses/mastra-harness-chat/src/app/layout.tsx
similarity index 100%
rename from examples/harnesses/mastra-harness/src/app/layout.tsx
rename to examples/harnesses/mastra-harness-chat/src/app/layout.tsx
diff --git a/examples/harnesses/mastra-harness/src/app/page.tsx b/examples/harnesses/mastra-harness-chat/src/app/page.tsx
similarity index 100%
rename from examples/harnesses/mastra-harness/src/app/page.tsx
rename to examples/harnesses/mastra-harness-chat/src/app/page.tsx
diff --git a/examples/harnesses/mastra-harness/src/generated/system-prompt.txt b/examples/harnesses/mastra-harness-chat/src/generated/system-prompt.txt
similarity index 100%
rename from examples/harnesses/mastra-harness/src/generated/system-prompt.txt
rename to examples/harnesses/mastra-harness-chat/src/generated/system-prompt.txt
diff --git a/examples/harnesses/mastra-harness/src/hooks/use-system-theme.tsx b/examples/harnesses/mastra-harness-chat/src/hooks/use-system-theme.tsx
similarity index 100%
rename from examples/harnesses/mastra-harness/src/hooks/use-system-theme.tsx
rename to examples/harnesses/mastra-harness-chat/src/hooks/use-system-theme.tsx
diff --git a/examples/harnesses/mastra-harness/src/lib/harness-stream.ts b/examples/harnesses/mastra-harness-chat/src/lib/harness-stream.ts
similarity index 100%
rename from examples/harnesses/mastra-harness/src/lib/harness-stream.ts
rename to examples/harnesses/mastra-harness-chat/src/lib/harness-stream.ts
diff --git a/examples/harnesses/mastra-harness/src/lib/mastra-harness-chat.ts b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness-chat.ts
similarity index 100%
rename from examples/harnesses/mastra-harness/src/lib/mastra-harness-chat.ts
rename to examples/harnesses/mastra-harness-chat/src/lib/mastra-harness-chat.ts
diff --git a/examples/harnesses/mastra-harness/src/lib/mastra-harness.ts b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness.ts
similarity index 98%
rename from examples/harnesses/mastra-harness/src/lib/mastra-harness.ts
rename to examples/harnesses/mastra-harness-chat/src/lib/mastra-harness.ts
index 68587841a..20508a50f 100644
--- a/examples/harnesses/mastra-harness/src/lib/mastra-harness.ts
+++ b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness.ts
@@ -71,7 +71,7 @@ function toolCategoryResolver(toolName: string): ToolCategory {
}
function createHarness() {
- mkdirSync(join(process.cwd(), ".mastra-harness"), { recursive: true });
+ mkdirSync(join(process.cwd(), ".mastra-harness-chat"), { recursive: true });
const agent = new Agent({
id: "openui-mastra-harness-agent",
@@ -87,7 +87,7 @@ function createHarness() {
id: "openui-mastra-harness",
storage: new LibSQLStore({
id: "openui-mastra-harness-storage",
- url: process.env.MASTRA_HARNESS_DB_URL || "file:./.mastra-harness/openui-harness.db",
+ url: process.env.MASTRA_HARNESS_DB_URL || "file:./.mastra-harness-chat/openui-harness.db",
}),
agent,
defaultModeId: "default",
diff --git a/examples/harnesses/mastra-harness/src/lib/thread-store.ts b/examples/harnesses/mastra-harness-chat/src/lib/thread-store.ts
similarity index 95%
rename from examples/harnesses/mastra-harness/src/lib/thread-store.ts
rename to examples/harnesses/mastra-harness-chat/src/lib/thread-store.ts
index 1545d4461..6deefe923 100644
--- a/examples/harnesses/mastra-harness/src/lib/thread-store.ts
+++ b/examples/harnesses/mastra-harness-chat/src/lib/thread-store.ts
@@ -8,8 +8,8 @@ export interface KVStorage {
removeItem(key: string): void;
}
-const THREADS_KEY = "mastra-harness-openui:threads";
-const messagesKey = (threadId: string) => `mastra-harness-openui:messages:${threadId}`;
+const THREADS_KEY = "mastra-harness-chat-openui:threads";
+const messagesKey = (threadId: string) => `mastra-harness-chat-openui:messages:${threadId}`;
function readJson(storage: KVStorage, key: string, fallback: T): T {
try {
diff --git a/examples/harnesses/mastra-harness/src/library.ts b/examples/harnesses/mastra-harness-chat/src/library.ts
similarity index 100%
rename from examples/harnesses/mastra-harness/src/library.ts
rename to examples/harnesses/mastra-harness-chat/src/library.ts
diff --git a/examples/harnesses/mastra-harness/tsconfig.json b/examples/harnesses/mastra-harness-chat/tsconfig.json
similarity index 100%
rename from examples/harnesses/mastra-harness/tsconfig.json
rename to examples/harnesses/mastra-harness-chat/tsconfig.json
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7199b8bb6..a5845ebe4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -380,7 +380,7 @@ importers:
specifier: ^5
version: 5.9.3
- examples/harnesses/mastra-harness:
+ examples/harnesses/mastra-harness-chat:
dependencies:
'@mastra/core':
specifier: ^1.46.0