Tool: {inv.toolName}{'result' in inv ? 'Done' : 'Running...'}
{'result' in inv ? (
{JSON.stringify(inv.result, null, 2)}
) : (
)}
))}
))}
);
}
```
#### 4. Multimodal Attachments (Images, PDFs & Audio)
Pass multimodal file buffers or URLs directly into `streamText` message arrays:
```typescript
import { google } from '@ai-sdk/google';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { prompt, pdfBase64, imageBase64 } = await req.json();
// Invariant: Gracefully fall back to Gemini 3.8 Flash if Gemini 4 Argon is unprovisioned
let modelInstance;
try {
modelInstance = google('gemini-4-argon');
} catch (err) {
console.warn('[VercelAISDK] Gemini 4 Argon unavailable. Falling back to Gemini 3.8 Flash:', err);
modelInstance = google('gemini-3.8-flash');
}
const result = streamText({
model: modelInstance,
messages: [
{
role: 'user',
content: [
{ type: 'text', text: prompt },
{ type: 'file', mimeType: 'application/pdf', data: pdfBase64 },
{ type: 'image', image: imageBase64 },
],
},
],
});
return result.toDataStreamResponse();
}
```
#### 5. Custom LanguageModelV1 Middleware (`wrapLanguageModel`)
Implement security screening, prompt caching telemetry, or rate limiting via unified middleware:
```typescript
import { anthropic } from '@ai-sdk/anthropic';
import { experimental_wrapLanguageModel as wrapLanguageModel } from 'ai';
export const auditedModel = wrapLanguageModel({
model: anthropic('claude-sonnet-5.5-20261022'),
middleware: {
wrapGenerate: async ({ doGenerate, params }) => {
console.log(`[Audit Middleware] Pre-generation prompt tokens: ${params.prompt.length}`);
const result = await doGenerate();
console.log(`[Audit Middleware] Generated tokens: ${result.text?.length ?? 0}`);
return result;
},
wrapStream: async ({ doStream, params }) => {
console.log(`[Audit Middleware] Initiating stream for model: ${params.modelId}`);
return await doStream();
},
},
});
```
#### 6. Direct Data Stream Control with `createDataStreamResponse`
Send custom progress updates, telemetry events, and citations alongside model tokens:
```typescript
import { anthropic } from '@ai-sdk/anthropic';
import { createDataStreamResponse, streamText } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
return createDataStreamResponse({
execute: async (dataStream) => {
// 1. Send initial telemetry annotation
dataStream.writeMessageAnnotation({ step: 'INITIALIZING_AUDIT', timestamp: Date.now() });
// 2. Stream LLM tokens (with Claude Opus 5.5 -> Claude Opus 4.6 fallback support)
let modelInstance;
try {
modelInstance = anthropic('claude-opus-5.5-20261022');
} catch (err) {
console.warn('[VercelAISDK] Claude Opus 5.5 unavailable. Falling back to Claude Opus 4.6:', err);
modelInstance = anthropic('claude-opus-4.6');
}
const result = streamText({
model: modelInstance,
messages,
});
result.mergeIntoDataStream(dataStream);
},
});
}
```
### Sovereign Execution, Token Efficiency & Invariants
| Dimension | Sovereign Mandate & Deterministic Contract |
| :--- | :--- |
| **Frontier Model Cascade** | Medium / High (`GPT-5.6 Sol Medium`, `Gemini 4 Argon`, `Claude Sonnet 5.5 High`, `Grok 4.7 High Fast`) |
| **Availability Fallback** | `Gemini 4 Argon/Pro` -> `Gemini 3.8 Flash`; `Claude Opus 5.5` -> `Claude Opus 4.6` (Zero unhandled missing-model errors) |
| **KV-Cache & Token Protocol** | Pin static instructions & schemas at prompt prefix (`kv-cache-prefix-optimizer`); pass surgical `CONTEXT_MAP.md` slices (<250 tokens/call) during Swarm Fan-Out |
| **SaaT CLI & MCP Dispatch** | CLI: `vibes skill exec vercel-ai-sdk-expert ` / MCP: `vibes_skill_dispatch`, `vibes_ast_query`, `vibes_compile_cache`, `vibes_optimize_budget`, `vibes_verify_gate` |
| **NFR & Anti-Slop Invariants** | P99 API Gateway Latency < 85ms, OpenAPI 3.1 / TypeSpec strict schema parity, RFC 9457 Problem Details error contracts, Idempotency-Key enforcement; 100% complete zero-placeholder output verified via `node scripts/check-anti-slop.js --strict` |
---
---
## Bahasa Indonesia
### Integrasi Orkestrasi
- **Model Hulu & Transport**: `ai-llm-integration-expert`, `frontier-ai-models-expert`, `gemini-agent-booster`
- **Presentasi Frontend & Generative UI**: `senior-frontend`, `nextjs-app-router-expert`, `ephemeral-generative-ui-architect`
- **Tooling & Swarm**: `mcp-server-architect`, `multi-agent-orchestration`, `parallel-tool-orchestrator`
- **Kontrak & Skema**: `structured-output-contracts`, `form-validation-expert`, `typescript-expert`
- **Siklus Hidup & Tata Kelola**: `zero-to-prod-orchestrator`, `session-memory-manager`, `anti-slop`
### Deskripsi
Panduan produksi untuk membangun aplikasi AI menggunakan **Vercel AI SDK (Core & UI)**. Mencakup abstraksi penyedia model terpadu (`@ai-sdk/anthropic`, `@ai-sdk/openai`, `@ai-sdk/google`), streaming teks dan objek terstruktur (`streamText`, `streamObject`), siklus eksekusi tool multi-langkah otonom dengan `maxSteps`, hook klien React 19 (`useChat`, `useCompletion`), streaming respons saluran data (`createDataStreamResponse`), dan rendering Generative UI.
**Sinergi Swarm:** Di dalam **Frontend & UI Swarm**, skill ini berperan sebagai Pemimpin Presentasi UI AI. Skill ini bertugas mentransformasikan keluaran multi-agen backend dan token streaming menjadi komponen web yang interaktif, aksesibel, dan elegan pada Fase 4 & Fase 5.
### Kondisi Pemicu
- Mengintegrasikan chat percakapan, streaming respons, atau generative UI di React 19 / Next.js 15.
- Menerapkan ekstraksi data terstruktur dengan validasi skema Zod via `generateObject` atau `streamObject`.
- Membangun loop pemanggilan tool (*tool-calling loops*) multi-langkah di Route Handler atau Server Actions.
- Beralih fleksibel antar penyedia model frontier (Claude Sonnet 5.5 / Fable 5.1, Gemini 4 Argon / Pro, OpenAI GPT-5.6 Sol, Grok 4.7, Ollama).
- Mengelola status eksekusi tool, indikator loading, dan rendering komponen UI secara dinamis saat streaming berlangsung.
---
### Implementasi Pola Kunci (TypeScript & React 19)
#### 1. Next.js 15 Route Handler dengan Multi-Step Tool Calling & Hooks Langkah
Gunakan `streamText` dengan `maxSteps: 10`, `onStepFinish`, dan prompt caching native untuk siklus pemanggilan tool iteratif otonom:
```typescript
// app/api/chat/route.ts
import { anthropic } from '@ai-sdk/anthropic';
import { streamText, tool } from 'ai';
import { z } from 'zod';
export const maxDuration = 60; // Izinkan penalaran agen hingga 60 detik
export async function POST(req: Request) {
const { messages } = await req.json();
const hasil = streamText({
model: anthropic('claude-sonnet-5.5-20261022'),
messages,
maxSteps: 10, // Siklus iteratif pemanggilan tool hingga 10 langkah
providerOptions: {
anthropic: {
cacheControl: { type: 'ephemeral' }, // Prompt caching untuk akselerasi TTFT hingga 90%
},
},
tools: {
hitungMetrikPerforma: tool({
description: 'Menghitung metrik analitik aplikasi dari data deret waktu mentah',
parameters: z.object({
datasetId: z.string().min(1),
metrik: z.enum(['p95_latensi', 'tingkat_error', 'throughput']),
}),
execute: async ({ datasetId, metrik }) => {
const data = await ambilMetrikSistem(datasetId, metrik);
return { datasetId, metrik, nilai: data.hasil, timestamp: new Date().toISOString() };
},
}),
},
system: 'Anda adalah auditor performa perangkat lunak elit. Selalu sertakan bukti valid dari pemanggilan tool.',
onStepFinish: ({ stepType, text, toolCalls, toolResults, finishReason, usage }) => {
console.log(`[Langkah ${stepType}] Status: ${finishReason}, Prompt Tokens: ${usage.promptTokens}, Completion: ${usage.completionTokens}`);
if (toolCalls && toolCalls.length > 0) {
console.log(`Tool dipanggil: ${toolCalls.map(t => t.toolName).join(', ')}`);
}
},
});
return hasil.toDataStreamResponse();
}
async function ambilMetrikSistem(datasetId: string, metrik: string) {
return { hasil: metrik === 'p95_latensi' ? '12.4ms' : '0.01%' };
}
```
#### 2. Streaming Objek Terstruktur Type-Safe (`streamObject`)
Streaming objek terstruktur tervalidasi skema Zod secara instan ke antarmuka klien:
```typescript
import { google } from '@ai-sdk/google';
import { streamObject } from 'ai';
import { z } from 'zod';
export const SkemaLaporanKeamanan = z.object({
kerentananKeamanan: z.array(z.object({
tingkatKeparahan: z.enum(['rendah', 'sedang', 'tinggi', 'kritis']),
cwe: z.string(),
penjelasan: z.string(),
saranPerbaikan: z.string(),
})),
skorRisikoGlobal: z.number().min(0).max(100),
lolosReview: z.boolean(),
ringkasanMitigasi: z.string(),
});
export async function POST(req: Request) {
const { diffKode } = await req.json();
// Invarian: Pengalihan otomatis ke Gemini 3.8 Flash jika Gemini 4 Pro belum aktif
let modelTarget;
try {
modelTarget = google('gemini-4-pro');
} catch (galat) {
console.warn('[VercelAISDK] Gemini 4 Pro belum tersedia. Mengalihkan ke Gemini 3.8 Flash:', galat);
modelTarget = google('gemini-3.8-flash');
}
const hasil = streamObject({
model: modelTarget,
schema: SkemaLaporanKeamanan,
prompt: `Audit perubahan kode berikut untuk potensi regresi keamanan:\n${diffKode}`,
});
return hasil.toTextStreamResponse();
}
```
#### 3. Integrasi Hook Klien React 19 (`useChat` dengan Invokasi Tool & Persetujuan)
Render token streaming, akordion penalaran (*thinking process*), dan persetujuan eksekusi tool interaktif:
```tsx
'use client';
import { useChat } from '@ai-sdk/react';
export function AntarmukaChatAgen() {
const { messages, input, handleInputChange, handleSubmit, isLoading, addToolResult } = useChat({
maxSteps: 10,
});
return (
{messages.map((m) => (
{/* Bagian Penalaran Model / Thinking Process */}
{m.parts?.map((bagian, index) => {
if (bagian.type === 'reasoning') {
return (
Proses Penalaran (Thinking)