feat: add AI agent dispatch panel with floating button and new task button on agents page

This commit is contained in:
2026-07-29 19:27:17 +00:00
parent d951348372
commit 449eade4b6
4 changed files with 278 additions and 6 deletions
+10 -5
View File
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { DispatchPanel } from '@/components/agents/dispatch-panel';
interface Agent {
id: string;
@@ -164,11 +165,15 @@ export default function AgentsPage() {
return (
<div>
<div className="mb-6">
<h1 className="text-2xl font-bold">Agent Activity</h1>
<p className="mt-1 text-muted-foreground">
Every agent action, visible and reversible.
</p>
<div className="mb-6 flex items-start justify-between">
<div>
<h1 className="text-2xl font-bold">Agent Activity</h1>
<p className="mt-1 text-muted-foreground">
Every agent action, visible and reversible.
</p>
</div>
<DispatchPanel triggerLabel="+ New task" triggerVariant="default" />
</div>
{feedback && (
<p
className={`mt-3 text-sm ${
+9
View File
@@ -4,6 +4,7 @@ import { NetworkErrorBanner } from '@/components/network-error-banner';
import { KeyboardShortcutsProvider } from '@/components/keyboard-shortcuts-provider';
import { WebVitalsTracker } from '@/components/web-vitals-tracker';
import { MobileBottomNav } from '@/components/mobile-bottom-nav';
import { DispatchPanel } from '@/components/agents/dispatch-panel';
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
@@ -23,6 +24,14 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
</div>
</div>
<MobileBottomNav />
{/* Floating AI dispatch button */}
<div className="fixed bottom-6 right-6 z-50">
<DispatchPanel
triggerLabel="Ask AI"
triggerVariant="default"
triggerClassName="h-12 w-12 rounded-full shadow-lg md:h-auto md:w-auto md:rounded-md md:px-4 md:py-2"
/>
</div>
<div className="sr-only" aria-live="polite" aria-atomic="true" id="a11y-announcer" />
</KeyboardShortcutsProvider>
);
+24 -1
View File
@@ -4,8 +4,10 @@
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
import { createAgentTaskSchema } from '@project-e/shared';
import { z } from 'zod';
// GET /api/agent-tasks — List agent tasks
export const GET = withAuth(async (request: NextRequest) => {
@@ -27,3 +29,24 @@ export const GET = withAuth(async (request: NextRequest) => {
perPage: result.perPage,
});
});
// POST /api/agent-tasks — Create a new agent task
export const POST = withAuth(async (request: NextRequest) => {
try {
const body = await request.json();
const data = createAgentTaskSchema.parse(body);
const pb = createPocketBaseClient();
const task = await pb.collection('agent_tasks').create({
...data,
status: 'pending',
});
return NextResponse.json(task, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError) {
return createErrorResponse('VALIDATION_ERROR', 'Invalid input', 400, error.issues);
}
throw error;
}
});