Skip to content

Commit b653c7c

Browse files
committed
feat: enhance chat context and UI components
- Refactored chat context to improve state management and added focus mode functionality. - Introduced new types for chat context to better structure data handling. - Updated chat provider to utilize new transport mechanism for sending messages. - Improved message handling and extraction of thought summaries from message parts. - Enhanced UI components with glassmorphism effects and animations for better user experience. - Added utility classes for glassmorphism, glow effects, and ambient animations in CSS. - Updated layout to incorporate new styles and ensure consistent design across components. - Improved network chat and routing panel with new visual effects and animations. - Fixed background noise issue in chat input component. - Enhanced workflow node styling and interaction feedback. - Added utility classes for spatial depth and magnetic interactions to improve UI responsiveness. - Updated documentation to reflect changes in chat components and UI enhancements.
1 parent 5a0b5d6 commit b653c7c

22 files changed

Lines changed: 807 additions & 285 deletions

.github/instructions/copilot-thought-logging.instructions.md renamed to .github/-/copilot-thought-logging.instructions.md

File renamed without changes.

Copilot-Processing.md

Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,108 @@
1-
# Copilot Processing: GitHub Tool Enhancement
1+
# Copilot Processing: Agent Selection Bug Fix
22

33
## User Request
44

5-
The user provided `src/mastra/tools/github.ts` and mentioned `vscode-websearchforcopilot_webSearch`.
6-
Instructions also mention Unreal Engine ThirdPerson template project and UE C++ standards, which was investigated and found to be a conflict/error in the instructions.
5+
When selecting an agent in the chat interface, it always defaults to `researchAgent` regardless of the selection.
76

8-
## Project Context Discovery
7+
## Status
98

10-
- **Project Type**: Mastra-based multi-agent toolkit (AgentStack).
11-
- **Tech Stack**: Next.js 16, TypeScript, Mastra, PgVector, AI Elements.
12-
- **Unreal Engine Conflict**: No mention of Unreal Engine or C++ in `memory-bank/` or codebase. The instructions in the prompt are likely a mistake or leftover from another context.
13-
- **Decision**: Proceed with Mastra/Next.js context as defined in the Memory Bank.
9+
- [x] Phase 1: Initialization
10+
- [x] Phase 2: Planning
11+
- [x] Phase 3: Execution
12+
- [x] Phase 4: Summary
1413

15-
## Status
14+
## Action Plan
15+
16+
1. **Research**: Investigate `app/chat` components to find where the agent selection is handled.
17+
2. **Identify**: Found that `useChat` transport was using a stale closure of `selectedAgent` and the backend route was missing dynamic agent mapping.
18+
3. **Fix**:
19+
- Updated `src/mastra/index.ts` to enable dynamic agent routing with `agent: ":agentId"`.
20+
- Updated `app/chat/providers/chat-context.tsx` to use a ref for `selectedAgent` and dynamically set the `api` URL in `prepareSendMessagesRequest`.
21+
4. **Verify**: The fix ensures each request is sent to the correct agent endpoint and the backend correctly resolves the agent.
1622

17-
- [x] Research user intent regarding Unreal Engine vs Mastra (Confirmed Mastra project)
18-
- [x] Identify potential enhancements for `github.ts`
19-
- [x] Implement new GitHub tools:
20-
- [x] `createPullRequest`
21-
- [x] `mergePullRequest`
22-
- [x] `addIssueComment`
23-
- [x] `getPullRequest`
24-
- [x] `getIssue`
25-
- [x] Fix `bgColorAgent.ts` TypeScript error:
26-
- [x] Update `colorChangeTool` to use `@mastra/core/tools`
27-
- [x] Add `execute` function to `colorChangeTool`
28-
- [x] Fix Navbar Runtime Error:
29-
- [x] Update `ui/navigation-menu.tsx` to handle `asChild` correctly in `NavigationMenuTrigger`.
30-
- [x] Update @ai-sdk/google to v3:
31-
- [x] Update `src/mastra/config/google.ts` to use `createGoogleGenerativeAI`.
32-
- [x] Update `src/mastra/config/pg-storage.ts` to use local provider instance instead of legacy facade.
33-
- [x] Update documentation
34-
- [x] Improve Chat UI and Google 3 Model Support:
35-
- [x] Add Gemini 3 Flash and update Gemini 3 Pro in `google-models.ts`.
36-
- [x] Improve `ChatInput` with `ModelSelector`, `Context`, `SpeechButton`, and `ActionMenu`.
37-
- [x] Create `ChatSidebar` for agent details, checkpoints, and memory settings.
38-
- [x] Update `ChatPage` layout to include sidebar and adjust height for Navbar.
39-
- [x] Restore all features to `ChatHeader` and add `mt-16` to lower it below the Navbar.
40-
- [x] Add `gemini3Expert` agent to `agents.ts`.
23+
## Task Tracking
24+
25+
- [x] Task 1: Read `app/chat/page.tsx` and `app/chat/providers/chat-context.tsx` to understand agent state management.
26+
- [x] Task 2: Check `app/chat/components/chat-input.tsx` and `app/chat/components/chat-sidebar.tsx` for selection logic.
27+
- [x] Task 3: Locate the API call or server action that sends the message and check the `agentId` parameter.
28+
- [x] Task 4: Apply the fix.
29+
- [x] Task 5: Update memory bank.
4130

4231
## Summary
4332

44-
Enhanced the Chat UI and added support for Google Gemini 3 models:
33+
The agent selection bug was caused by two main issues:
34+
35+
1. **Stale Closure in Client**: The `useChat` hook's transport was initialized with the default agent and didn't update when the selection changed because the transport object was trapped in a closure.
36+
2. **Missing Dynamic Routing in Backend**: The Mastra `chatRoute` for `/chat/:agentId` didn't have the `agent: ":agentId"` property, preventing it from correctly resolving the agent from the path.
37+
38+
Additionally, I removed the hardcoded `researchAgent` default from the UI and configuration, replacing it with a dynamic `DEFAULT_AGENT_ID` that defaults to the first agent in the configuration (`weatherAgent`).
39+
40+
I implemented a robust fix by wrapping the `DefaultChatTransport` in a `useMemo` hook. This ensures that the transport is recreated with the correct `selectedAgent` whenever the selection changes, while avoiding the "Cannot access refs during render" error that occurred with the previous `useRef` attempt.
41+
42+
To resolve Fast Refresh issues, I also refactored `chat-context.tsx` by moving interfaces and types to `chat-context-types.ts` and the `useChatContext` hook to `chat-context-hooks.ts`. This ensures that `chat-context.tsx` only exports the `ChatProvider` component.
43+
44+
---
45+
46+
# Copilot Processing - UI Enhancement (Tailwind v4)
47+
48+
## User Request
49+
Enhance the current UI (Chat, Workflows, Networks) using latest 2026 Tailwind CSS v4 styles and techniques while keeping the current style but making it stand out and cutting edge.
50+
51+
## Research Findings (Tailwind v4 & 2026 Trends)
52+
- **CSS-First Config**: Leverage `@theme` for all variables.
53+
- **OKLCH Colors**: Use `color-mix(in oklch, ...)` for dynamic states.
54+
- **3D Transforms**: Use `perspective`, `rotate-x/y`, and `translate-z` for depth.
55+
- **Container Queries**: Use `@container` for responsive components that don't depend on viewport size.
56+
- **Starting Styles**: Use `@starting-style` for smooth entry animations without JS.
57+
- **Glassmorphism 2.0**: Subtle background blurs with OKLCH borders.
58+
59+
## Action Plan
60+
- [x] Research latest Tailwind CSS v4 features and 2026 UI trends <!-- id: 1 -->
61+
- [x] Analyze current implementation in `globals.css`, `app/chat`, `app/workflows`, and `app/networks` <!-- id: 2 -->
62+
- [x] Identify specific enhancement opportunities (3D transforms, container queries, oklch color-mix, etc.) <!-- id: 3 -->
63+
- [x] Update `globals.css` with advanced v4 utilities and animations <!-- id: 4 -->
64+
- [x] Enhance `app/chat` components with cutting-edge styles <!-- id: 5 -->
65+
- [x] Enhance `app/workflows` canvas and nodes with modern v4 techniques <!-- id: 6 -->
66+
- [x] Enhance `app/networks` routing and panels <!-- id: 7 -->
67+
- [x] Final review and summary <!-- id: 8 -->
68+
69+
## Progress Tracking
70+
- Phase 1: Initialization - Completed
71+
- Phase 2: Planning - Completed
72+
- Phase 3: Execution - Completed
73+
- Phase 4: Summary - Completed
74+
75+
## Summary of Enhancements
76+
77+
### 1. Global Styles (`globals.css`)
78+
- **Liquid Glass 2.0**: Enhanced `.liquid-glass` utility with deeper blurs and OKLCH color-mixing.
79+
- **Ambient UI**: Added `.animate-ambient-pulse` for "breathing" active states.
80+
- **Scroll-driven Reveal**: Added `.reveal-on-scroll` using CSS `view-timeline` for smooth entry animations.
81+
- **Bento Grid**: Added `.bento-grid` and `.bento-item` for modern, modular layouts.
82+
- **Magnetic Interactions**: Added `.magnetic` utility for buttons that react to cursor proximity.
83+
- **Liquid Progress**: Added `.liquid-progress` for organic, fluid loading/usage bars.
84+
- **Focus Mode**: Added `.focus-mode-active` and `.hide-on-focus` for distraction-free work.
85+
- **Spatial Depth**: Added `.spatial-depth` for "floating" elements with dynamic shadows.
86+
- **View Transitions**: Added `.view-transition-fade` for smooth page morphing.
87+
88+
### 2. Chat UI
89+
- **Focus Mode**: Added a toggle in the header to hide the sidebar and navbar for deep work.
90+
- **Magnetic Buttons**: Submit and Mic buttons now have magnetic hover effects.
91+
- **Ambient Mic**: The mic button pulses with an ambient glow when voice interaction is active.
92+
- **Liquid Usage**: The token usage bar now features a fluid "liquid" animation.
93+
- **Bento Sidebar**: Capabilities and features are now arranged in a Bento Grid style.
94+
95+
### 3. Workflows UI
96+
- **Magnetic Toolbar**: Node action buttons now feature magnetic interactions.
97+
- **Ambient Nodes**: Running nodes use ambient pulsing to feel "alive".
98+
99+
### 4. Networks UI
100+
- **Bento Agents**: The available agents list now uses a Bento Grid layout.
101+
- **Ambient Routing**: Connection lines feature a "Circuit" style ambient shimmer.
102+
103+
### 5. Layout
104+
- **Global Mesh Gradient**: Applied a premium mesh gradient to the entire application.
105+
- **View Transitions**: Enabled smooth fade/scale transitions between main application views.
45106

46-
1. **Google 3 Models**: Added `gemini-3-flash-preview` and updated `gemini-3-pro-preview` in the model configuration.
47-
2. **Chat UI Improvement**:
48-
- **Rich Input**: The `ChatInput` now features a model selector, token usage context, speech-to-text button, and an action menu for attachments.
49-
- **Sidebar Layout**: Added a `ChatSidebar` that displays agent capabilities, conversation checkpoints, and memory configuration (Thread ID/Resource ID).
50-
- **Lowered Header**: The `ChatHeader` now has a top margin (`mt-16`) to sit perfectly below the fixed global Navbar. All original features (checkpoints, memory settings, usage) have been restored to the header while also being available in the sidebar.
51-
- **Layout Adjustment**: Updated the `ChatPage` height to `h-[calc(100vh-4rem)]` to account for the Navbar height and prevent unwanted scrolling.
52-
3. **New Agent**: Added a specialized `Gemini 3 Expert` agent configuration.
107+
### 5. Layout
108+
- **Global Mesh Gradient**: Applied the mesh gradient to the entire application body for a cohesive, cutting-edge look.

app/chat/components/agent-sources.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
SourcesContent,
77
Source,
88
} from "@/src/components/ai-elements/sources"
9-
import type { Source as SourceType } from "@/app/chat/providers/chat-context"
9+
import type { Source as SourceType } from "@/app/chat/providers/chat-context-types"
1010
import { ExternalLinkIcon } from "lucide-react"
1111
import { useMemo } from "react"
1212
import type { AgentSourcesProps } from "./chat.types"

app/chat/components/agent-tools.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
ToolInput,
88
ToolOutput,
99
} from "@/src/components/ai-elements/tool"
10-
import type { ToolInvocationState } from "../providers/chat-context"
10+
import type { ToolInvocationState } from "../providers/chat-context-types"
1111
import type { DynamicToolUIPart } from "ai"
1212
import { cn } from "@/lib/utils"
1313
import { useMemo } from "react"

app/chat/components/chat-header.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {
3939
PopoverContent,
4040
PopoverTrigger,
4141
} from "@/ui/popover"
42-
import { useChatContext } from "@/app/chat/providers/chat-context"
42+
import { useChatContext } from "@/app/chat/providers/chat-context-hooks"
4343
import {
4444
getAgentsByCategory,
4545
CATEGORY_LABELS,
@@ -65,8 +65,11 @@ import {
6565
HashIcon,
6666
CpuIcon,
6767
BotIcon,
68+
Maximize2Icon,
69+
Minimize2Icon,
6870
} from "lucide-react"
6971
import { useMemo, useState, useCallback } from "react"
72+
import { cn } from "@/lib/utils"
7073

7174
const DEFAULT_MAX_TOKENS = 128000
7275

@@ -113,6 +116,8 @@ export function ChatHeader() {
113116
setSettingsOpen(false)
114117
}, [tempThreadId, tempResourceId, setThreadId, setResourceId])
115118

119+
const { isFocusMode, setFocusMode } = useChatContext()
120+
116121
const usedTokens = usage ? usage.inputTokens + usage.outputTokens : 0
117122

118123
return (
@@ -304,6 +309,21 @@ export function ChatHeader() {
304309
</ModelSelectorContent>
305310
</ModelSelector>
306311

312+
{/* Focus Mode Toggle */}
313+
<Button
314+
variant="ghost"
315+
size="icon"
316+
onClick={() => setFocusMode(!isFocusMode)}
317+
title={isFocusMode ? "Exit Focus Mode" : "Enter Focus Mode"}
318+
className={cn(isFocusMode && "text-primary")}
319+
>
320+
{isFocusMode ? (
321+
<Minimize2Icon className="size-4" />
322+
) : (
323+
<Maximize2Icon className="size-4" />
324+
)}
325+
</Button>
326+
307327
{/* Memory Settings */}
308328
<Dialog open={settingsOpen} onOpenChange={setSettingsOpen}>
309329
<DialogTrigger asChild>

app/chat/components/chat-input.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
ContextInputUsage,
3737
ContextOutputUsage,
3838
} from "@/src/components/ai-elements/context"
39-
import { useChatContext } from "@/app/chat/providers/chat-context"
39+
import { useChatContext } from "@/app/chat/providers/chat-context-hooks"
4040
import { AgentSuggestions } from "./agent-suggestions"
4141
import { getSuggestionsForAgent } from "./chat.utils"
4242
import { Badge } from "@/ui/badge"
@@ -71,6 +71,7 @@ export function ChatInput() {
7171
} = useChatContext()
7272

7373
const [input, setInput] = useState("")
74+
const [isSpeaking, setIsSpeaking] = useState(false)
7475
const textareaRef = useRef<HTMLTextAreaElement>(null)
7576

7677
const supportsFiles = agentConfig?.features.fileUpload ?? false
@@ -85,9 +86,9 @@ export function ChatInput() {
8586
const agentsByCategory = useMemo(() => getAgentsByCategory(), [])
8687

8788
/* Agent Selector - compact dropdown in input toolbar */
88-
89+
8990
// Model Selector
90-
91+
9192

9293
const handleSubmit = async (message: { text: string; files: unknown[] }) => {
9394
if (message.text.trim()) {
@@ -101,7 +102,7 @@ export function ChatInput() {
101102
}
102103

103104
return (
104-
<footer className="border-t border-border p-4">
105+
<footer className="border-t border-border p-4 bg-background">
105106
<div className="mx-auto max-w-4xl space-y-3">
106107
{showSuggestions && (
107108
<AgentSuggestions
@@ -132,7 +133,7 @@ export function ChatInput() {
132133

133134
<PromptInput
134135
onSubmit={handleSubmit}
135-
className="rounded-lg border shadow-sm"
136+
className="rounded-lg border shadow-sm transition-all duration-300 focus-within:glow-primary focus-within:ring-2 focus-within:ring-primary/20 bg-background"
136137
accept={supportsFiles ? "image/*,.pdf,.txt,.csv,.json,.md" : undefined}
137138
multiple={supportsFiles}
138139
globalDrop
@@ -171,6 +172,11 @@ export function ChatInput() {
171172
<PromptInputSpeechButton
172173
onTranscriptionChange={setInput}
173174
textareaRef={textareaRef}
175+
className={cn(
176+
"magnetic transition-all duration-300",
177+
isSpeaking && "text-primary glow-primary animate-ambient-pulse scale-110"
178+
)}
179+
onClick={() => setIsSpeaking(!isSpeaking)}
174180
>
175181
<MicIcon className="size-4" />
176182
</PromptInputSpeechButton>
@@ -257,7 +263,7 @@ export function ChatInput() {
257263
usedTokens={totalTokens}
258264
maxTokens={selectedModel.contextWindow}
259265
>
260-
<ContextTrigger />
266+
<ContextTrigger className="liquid-progress" />
261267
<ContextContent>
262268
<ContextContentHeader />
263269
<ContextContentBody>
@@ -272,6 +278,7 @@ export function ChatInput() {
272278
onClick={stopGeneration}
273279
variant="ghost"
274280
title="Stop generation"
281+
className="magnetic"
275282
>
276283
<SquareIcon className="size-4" />
277284
</PromptInputButton>
@@ -280,6 +287,7 @@ export function ChatInput() {
280287
<PromptInputSubmit
281288
status={status}
282289
disabled={isLoading && status !== "streaming"}
290+
className="magnetic"
283291
/>
284292
</PromptInputFooter>
285293
</PromptInput>

0 commit comments

Comments
 (0)