# Ai Native Ui

> A Claude skill from Leo-Atienza/atlas-claude.

- **Type:** Skill
- **Install:** `agentstack add skill-leo-atienza-atlas-claude-ai-native-ui`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Leo-Atienza](https://agentstack.voostack.com/s/leo-atienza)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Leo-Atienza](https://github.com/Leo-Atienza)
- **Source:** https://github.com/Leo-Atienza/atlas-claude/tree/main/skills/_archived/ai-native-ui

## Install

```sh
agentstack add skill-leo-atienza-atlas-claude-ai-native-ui
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# AI-Native UI

## When to Use This Skill

Load when building any UI with LLM integration: chat interfaces, AI-generated content, smart search, content generation tools, or any feature that streams AI responses to users.

This is **Tier 4 (Generative)** in the Vanguard architecture. Load `web-l100` (SK-083) for the full tier system.

---

## The Generative Tier

AI streams are a fundamentally different rendering model. Unlike T0-T3 where the final content is known at render time, T4 content builds up token-by-token with structural uncertainty. The UI must:

1. Show useful content immediately (PPR shell + cached content)
2. Progressively reveal AI-generated content as it streams
3. Handle tool invocations mid-stream (AI calls tools → UI renders components)
4. Gracefully handle interruption (user cancels, network drops)

---

## Core Pattern: streamText + Route Handler

### Server: Route Handler

```typescript
// app/api/chat/route.ts
import { streamText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: anthropic('claude-sonnet-4-5-20250514'),
    system: 'You are a helpful assistant.',
    messages,
    tools: {
      getWeather: {
        description: 'Get weather for a location',
        parameters: z.object({
          location: z.string().describe('City name'),
        }),
        execute: async ({ location }) => {
          const weather = await fetchWeather(location);
          return weather;
        },
      },
    },
  });

  return result.toDataStreamResponse();
}
```

### Client: useChat Hook

```tsx
// components/chat.tsx
'use client';
import { useChat } from '@ai-sdk/react';

export function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading, stop } = useChat({
    api: '/api/chat',
  });

  return (
    
      
        {messages.map(message => (
          
            {message.content}

            {/* Render tool invocations as components */}
            {message.toolInvocations?.map(invocation => (
              
            ))}
          
        ))}
      

      
        
        {isLoading ? (
          Stop
        ) : (
          Send
        )}
      
    
  );
}
```

---

## Tool Invocations → React Components

The killer pattern: AI calls tools, each tool invocation maps to a React component.

```tsx
// components/tool-result.tsx
function ToolResult({ invocation }: { invocation: ToolInvocation }) {
  // Tool is still being called — show loading state
  if (invocation.state === 'call') {
    return ;
  }

  // Tool returned a result — render the appropriate component
  if (invocation.state === 'result') {
    switch (invocation.toolName) {
      case 'getWeather':
        return ;
      case 'searchProducts':
        return ;
      case 'getChart':
        return ;
      default:
        return {JSON.stringify(invocation.result, null, 2)};
    }
  }

  return null;
}

function ToolLoading({ name }: { name: string }) {
  return (
    
      
    
  );
}
```

---

## Streaming Structured Objects

For streaming JSON objects (not just text) as they build up:

### Server: streamObject

```typescript
// app/api/analyze/route.ts
import { streamObject } from 'ai';
import { z } from 'zod';

const AnalysisSchema = z.object({
  summary: z.string(),
  sentiment: z.enum(['positive', 'negative', 'neutral']),
  keyTopics: z.array(z.string()),
  confidence: z.number(),
});

export async function POST(req: Request) {
  const { text } = await req.json();

  const result = streamObject({
    model: anthropic('claude-sonnet-4-5-20250514'),
    schema: AnalysisSchema,
    prompt: `Analyze this text: ${text}`,
  });

  return result.toTextStreamResponse();
}
```

### Client: useObject

```tsx
'use client';
import { useObject } from '@ai-sdk/react';

function AnalysisPanel({ text }: { text: string }) {
  const { object, isLoading } = useObject({
    api: '/api/analyze',
    schema: AnalysisSchema,
    body: { text },
  });

  return (
    
      {/* Fields appear progressively as AI generates them */}
      {object?.summary && {object.summary}}
      {object?.sentiment && }
      {object?.keyTopics && (
        
          {object.keyTopics.map(topic => {topic})}
        
      )}
      {object?.confidence != null && }
    
  );
}
```

---

## Generative UI within PPR

The T4 tier integrated with T0-T2. Static shell loads instantly, AI content fills in.

```tsx
// app/dashboard/page.tsx
export default function AIAssistantPage() {
  return (
    <>
      {/* T0: Static shell — instant from CDN */}
      AI Assistant

      {/* T1: Cached suggestions */}
      

      {/* T4: AI chat — streams in */}
      }>
        
      

      {/* T1: Cached documentation sidebar */}
      
    
  );
}
```

The user sees the full UI shell instantly, popular questions load from cache, and the AI chat is ready for interaction — all within 100ms. AI responses then stream in 1-3 seconds.

---

## Multi-Stream Orchestration

Multiple independent AI streams in one UI:

```tsx
function AIDashboard() {
  const summary = useChat({ api: '/api/ai/summary', id: 'summary' });
  const insights = useChat({ api: '/api/ai/insights', id: 'insights' });
  const predictions = useChat({ api: '/api/ai/predictions', id: 'predictions' });

  // Trigger all three on page load
  useEffect(() => {
    summary.append({ role: 'user', content: 'Summarize today' });
    insights.append({ role: 'user', content: 'Key insights' });
    predictions.append({ role: 'user', content: 'Predictions' });
  }, []);

  return (
    
      
      
      
    
  );
}
```

Each panel updates independently as its stream progresses.

---

## Error Handling & Cancellation

```tsx
const { messages, error, reload, stop, isLoading } = useChat({
  api: '/api/chat',
  onError: (error) => {
    console.error('Chat error:', error);
    // Show toast notification
  },
});

// Retry last message
{error && (
  Retry
)}

// Cancel in-progress generation
{isLoading && (
  Stop generating
)}
```

---

## Key Rules

1. **Use AI SDK UI (stable)**, not AI SDK RSC (experimental) for production
2. **Server returns data, client renders components** — clean separation of concerns
3. **Tool invocations are the bridge** between AI decisions and React components
4. **Always provide loading states** for tool invocations (skeleton matching final size)
5. **Wrap AI components in Suspense** for PPR integration
6. **Use `stop()`** — users expect to cancel long generations
7. **Stream objects when structure matters** — `streamObject` + `useObject` for dashboards, forms
8. **Cache common AI queries** — wrap with `use cache` for FAQ-style responses

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Leo-Atienza](https://github.com/Leo-Atienza)
- **Source:** [Leo-Atienza/atlas-claude](https://github.com/Leo-Atienza/atlas-claude)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-leo-atienza-atlas-claude-ai-native-ui
- Seller: https://agentstack.voostack.com/s/leo-atienza
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
